
[{"content":"","date":"October 2, 2026","externalUrl":null,"permalink":"/notes/","section":"Notes","summary":"","title":"Notes","type":"notes"},{"content":" What I\u0026rsquo;m doing now # Updated 2026-09-29, from Bratislava, Slovakia.\nWork # AI-supported software development and change-process consulting multiple side projects Learning how to be a better Wikipedian Building # ABM — a Python tool that manages my audiobook library (DRM-free purchases from Audioteka and AudioLibrix) Deduplication and integrity verification of decades of accumulated file archives The digital garden: this blog\u0026rsquo;s revival plus an Obsidian-vault-to-web publishing pipeline Meme-archive porting Istros.eu Website to Wordpress Learning # AI tooling Rust Italian Reading / Listening # Finished: Wallander Book 4 Listening: Ellis Peter\u0026rsquo;s Yorkshire murders series Reading: LazyVim for Ambitious Developers (Dusty Phillips) Reading: Suroviny a moc – geopolitika nerostného bohatství (Michel Jébrak) Life # Just back from Wikimedia Weekend Getting organized an October trip to Napoli This is a now page. If you have your own site, you should make one too.\n","date":"August 22, 2026","externalUrl":null,"permalink":"/now/","section":"Miro's World","summary":"What I’m doing now # Updated 2026-09-29, from Bratislava, Slovakia.\nWork # AI-supported software development and change-process consulting multiple side projects Learning how to be a better Wikipedian Building # ABM — a Python tool that manages my audiobook library (DRM-free purchases from Audioteka and AudioLibrix) Deduplication and integrity verification of decades of accumulated file archives The digital garden: this blog’s revival plus an Obsidian-vault-to-web publishing pipeline Meme-archive porting Istros.eu Website to Wordpress Learning # AI tooling Rust Italian Reading / Listening # Finished: Wallander Book 4 Listening: Ellis Peter’s Yorkshire murders series Reading: LazyVim for Ambitious Developers (Dusty Phillips) Reading: Suroviny a moc – geopolitika nerostného bohatství (Michel Jébrak) Life # Just back from Wikimedia Weekend Getting organized an October trip to Napoli This is a now page. If you have your own site, you should make one too.\n","title":"Now","type":"page"},{"content":"This is personal blog of Miro Adamy.\nThe same scene, as Gemini imagines it — DevOps edition.\nIm am DevOps/Cloud engineer, currently living in Bratislava, Slovakia and spending my days designing and creating software systems for living and pleasure, reading books, surfing Web, walking, thinking and enjoying life with my family\nResume # My current resume is available online or can be downloaded from here as PDF\nContact # Email me - firstname dot lastname, at Sergei\u0026rsquo;s and Larry\u0026rsquo;s company\u0026rsquo;s email\nDisclaimer # The thoughts and opinions expressed in this blog are mine and do not represent the position of my employer.\nBlog version # See version page for details\n","date":"August 20, 2017","externalUrl":null,"permalink":"/about/","section":"Miro's World","summary":"This is personal blog of Miro Adamy.\nThe same scene, as Gemini imagines it — DevOps edition.\nIm am DevOps/Cloud engineer, currently living in Bratislava, Slovakia and spending my days designing and creating software systems for living and pleasure, reading books, surfing Web, walking, thinking and enjoying life with my family\nResume # My current resume is available online or can be downloaded from here as PDF\n","title":"About","type":"page"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/","section":"Miro's World","summary":"","title":"Miro's World","type":"page"},{"content":" Status # hugo v0.166.0+extended+withdeploy darwin/arm64 BuildDate=2026-09-09T14:45:02Z VendorInfo=Homebrew\nPygments version 2.21.0, (c) 2006-present by Georg Brandl, Matthäus Chajdas and contributors.\nBlog commit: e8b7961a4e9a2fb995c0611b4e8bdd4734f8d28a\nTheme commit: 51a361e068b9975c7f1df8e2bb223db03fe49c2b\nPublished: \u0026ldquo;2026-10-03T15:18:54Z\u0026rdquo;\n","date":"October 3, 2026","externalUrl":null,"permalink":"/status/","section":"Miro's World","summary":"Status # hugo v0.166.0+extended+withdeploy darwin/arm64 BuildDate=2026-09-09T14:45:02Z VendorInfo=Homebrew\nPygments version 2.21.0, (c) 2006-present by Georg Brandl, Matthäus Chajdas and contributors.\nBlog commit: e8b7961a4e9a2fb995c0611b4e8bdd4734f8d28a\nTheme commit: 51a361e068b9975c7f1df8e2bb223db03fe49c2b\nPublished: “2026-10-03T15:18:54Z”\n","title":"status","type":"page"},{"content":"In July 2023 I sat down to list every place my files lived. The list had eight entries - seven online storages and one line for \u0026ldquo;external volumes\u0026rdquo; - and at the bottom a checkbox: \u0026ldquo;Finish this list\u0026rdquo;. It stayed unchecked for three years, which tells you everything about the problem.\nIn the earlier post about reorganizing my digital life I described the big picture: the Data Map, the disk catalog, the new NAS. This one zooms in on the clouds, one by one.\nThe zoo, as found # Two NAS boxes at home. A paid, end-to-end encrypted cloud (Tresorit). Two Google Drives, one personal and one for the company. iCloud, OneDrive, Dropbox, a backup service (Backblaze), some files in AWS S3, and a Notion workspace. Plus 23 external disks in a drawer.\nNone of them was chosen for a purpose. Each one grew a purpose by accident: downloads landed wherever the browser pointed, and when I retired an old computer, its files went to whichever storage had free space that week. I always believed every kind of information should have its home. The homes just multiplied faster than the rules.\nWhat each one became # Tresorit is gone - almost. I copied every file to the NAS and verified each one by checksum: 35,219 of 35,220. The one that did not make it was an empty PDF that could not be read even at the source. I did not delete anything there; the subscription simply runs out at the end of October, so if something turns out to be missing, it is still there until the last day.\nThe irony is not lost on me: the most European of my cloud providers is the one I am leaving. I am generally trying to depend less on American providers, but this decision was purely pragmatic. I needed something with an API, something Claude can work with on its own. Tresorit, however good at security and privacy, is primarily a tool for mirroring a local disk to the cloud. Perfect for a person with one computer, but not for my grand plan of bringing several tiers of storage back together. No API and patchy support for NAS and Linux made it the latest victim, after Backblaze.\niCloud was the biggest surprise. I started it as a cleanup and it turned into a rescue. About 250 GB in 187,000 files, and 91% of them were only placeholders on my Mac, with the real content in the cloud. Much of it came from old computers I had copied there years ago, and some of it existed nowhere else. What made it manageable was realizing that the drive breaks down into about fifteen decisions, not 187,000 files. Each old machine, each photo dump, each project folder is one decision. Checked against the disk catalog, the amount of data that existed only in iCloud went from 114 GB in early August to 16.6 GB in early September. Nothing has been deleted yet, and the 2 TB family plan stays. Space was never the problem.\nOneDrive lost its biggest job first. It held a 116 GB copy of my ebook library, which I deleted in July once the library had a proper home on the NAS. The surprise was on the Mac side: OneDrive also kept a hidden 44 GB local cache, which I only found when I went looking for missing disk space.\nMy company\u0026rsquo;s Google Drive (Klassify) turned out to be much smaller than its plan. Measured, it held 7 GB, so it moved from the 2 TB plan to the smallest one. My personal Google Drive is the honest open item: it is still not catalogued, and for now it is only a fallback.\nBackblaze was mercilessly cancelled. Its final export, 741 GB and 1.3 million files, sits on the NAS, now also in the offsite backup. Sorting what is actually in it is a project of its own, for later.\nDropbox and the Downloads folder are demoted to landing zones: things arrive there, and then they are supposed to drain into the NAS. \u0026ldquo;Supposed to\u0026rdquo; is doing a lot of work in that sentence - both cleanups are still on my list. The files in AWS S3 are on the same list.\nNotion is transitional. The content I care about now lives in my Obsidian vault and gets published from there. The old workspace stays dormant; the family pages will be unshared, not deleted, once the family actually uses the new sites.\nAnd the NAS is the master. Its shares are not split by content type but by how the content is used, and how sensitive it is: curated documents sit behind access control, while media is something any device I point at it may play. The old NAS is drained, and the disk catalog now knows about 10 million files, 12.8 TiB in total.\nThe rules that made it converge # One home per class of data. Everything else is either a copy or a funnel into that home.\nNothing is deleted from any cloud until the NAS has a backup plan for that class of data. A rescue must never leave me with fewer copies than before. That is why the offsite backup post comes before this one, and why the iCloud rescue has not deleted a single file yet.\nCatalogs before decisions. You cannot triage what you cannot enumerate. Every exit started by comparing the cloud against the disk catalog, and most of the time the answer was \u0026ldquo;you already have this\u0026rdquo;.\nWhere it stands # Fewer storages, each with a job. One paid subscription is running out, another is already cancelled, and the drawer of disks is now a searchable catalog. Still open: the personal Google Drive, the Dropbox and Downloads cleanups, and the rest of iCloud.\nAnd that checkbox from 2023? I can finally tick it - by deleting the list.\nThis was the last of the infrastructure posts. The two remaining parts of the series step away from disks and clouds. Part 11 goes back to the early 2000s, to a one-man company in Canada called Miro Adamy Software Solutions, and follows it through Thinknostic, Thinkwrap and an acquisition, back to a one-man company again. Part 12 is about what changed along the way, and what I want to do next.\nNext in this series: full circle, from a one-man company to a one-man company.\n","date":"October 3, 2026","externalUrl":null,"permalink":"/posts/2026-10-03-taming-the-online-storages/","section":"Posts","summary":"In July 2023 I sat down to list every place my files lived. The list had eight entries - seven online storages and one line for “external volumes” - and at the bottom a checkbox: “Finish this list”. It stayed unchecked for three years, which tells you everything about the problem.\nIn the earlier post about reorganizing my digital life I described the big picture: the Data Map, the disk catalog, the new NAS. This one zooms in on the clouds, one by one.\n","title":"Catching up: Taming the Online Storages","type":"post"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/tags/catching-up/","section":"Tags","summary":"","title":"Catching-Up","type":"tags"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/series/catching-up-2021-2026/","section":"Series","summary":"","title":"Catching-Up 2021-2026","type":"series"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/tags/cloud-storage/","section":"Tags","summary":"","title":"Cloud-Storage","type":"tags"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/tags/declutter/","section":"Tags","summary":"","title":"Declutter","type":"tags"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/tags/icloud/","section":"Tags","summary":"","title":"Icloud","type":"tags"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/categories/lifehacks/","section":"Categories","summary":"","title":"Lifehacks","type":"categories"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","date":"October 3, 2026","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"Na slovenskej Wikipédii je veľa červených odkazov - teda odkazov na články, ktoré zatiaľ neexistujú. Na to existuje šikovný nástroj: What to Blue, ktorý chýbajúce články zoradí podľa popularity, takže hneď vidno, ktorý nový článok by Wikipédii pomohol najviac.\nChvíľu som sa s ním hral a rozhodol som sa sústrediť na oblasť, ktorej rozumiem najviac: softvérové inžinierstvo, open source a ľudia zo sveta softvéru, ktorých pozná každý programátor, ale málokto iný. Na slovenskej Wikipédii sú výrazne podreprezentovaní. Ich články buď úplne chýbajú, alebo sú to len krátke výhonky - oveľa kratšie ako česká verzia, o anglickej ani nehovoriac. Špeciálnou kategóriou sú ženy v tejto oblasti - zastúpenie stránok venovaných ženám v Computer Science na slovenskej Wikipédii je hanebne žalostné.\nZačal som teda tieto články vytvárať a rozširovať. Zatiaľ mám zoznam približne 80 článkov na najbližšie týždne. Prvé sú už vonku: nový článok Larry Ellison, rozšírený Guido van Rossum, autor Pythonu, a nová Margaret Hamilton, ktorá písala softvér pre Apollo. Ďalší na rade je James Gosling, otec Javy, a niekoľko technologicky orientovaných článkov (Kubernetes, programovacie jazyky, cloudové technológie). Bude to zaujímavý challenge, keďže tieto články by nemali byť písané mojou obľúbenou voľnou zmesou angličtiny a slovenčiny, ale poriadne spisovne a hlavne s dodržiavaním terminológie, ktorú vo väčšine prípadov nepoužívam.\nČervené odkazy sa tak pomaly budú meniť na modré\u0026hellip; alespoň doufám (viď Zdeněk Svěrák v Záskoku)\nA ešte jeden shameless personal plug na záver: môj edit counter na Wikipédii presiahol 1000, aj keď drvivú väčšinu z nich tvoria jednoduché malé edity. Na vyjadrenie počtu vlastných článkov mi bohužiaľ stále stačia 4 bity. But it\u0026rsquo;s a start.\n","date":"October 2, 2026","externalUrl":null,"permalink":"/notes/what-to-blue/","section":"Notes","summary":"Na slovenskej Wikipédii je veľa červených odkazov - teda odkazov na články, ktoré zatiaľ neexistujú. Na to existuje šikovný nástroj: What to Blue, ktorý chýbajúce články zoradí podľa popularity, takže hneď vidno, ktorý nový článok by Wikipédii pomohol najviac.\nChvíľu som sa s ním hral a rozhodol som sa sústrediť na oblasť, ktorej rozumiem najviac: softvérové inžinierstvo, open source a ľudia zo sveta softvéru, ktorých pozná každý programátor, ale málokto iný. Na slovenskej Wikipédii sú výrazne podreprezentovaní. Ich články buď úplne chýbajú, alebo sú to len krátke výhonky - oveľa kratšie ako česká verzia, o anglickej ani nehovoriac. Špeciálnou kategóriou sú ženy v tejto oblasti - zastúpenie stránok venovaných ženám v Computer Science na slovenskej Wikipédii je hanebne žalostné.\n","title":"","type":"notes"},{"content":"Wikimedia Editaton - \u0026ldquo;Wiki miluje film\u0026rdquo; sa včera skončil. Tento rok editori slovenskej Wikipédie pridali 45 nových článkov na tému film, herci, seriály a všetko, čo súvisí s filmovým umením. Je to skoro 50% nárast oproti minulému roku. Samozrejme, som sa zapojil a tiež som prispel. Bola to zábava, naučil som sa veľa nových vecí pri hľadaní zdrojov a prekladaní článkov z anglickej a španielskej Wikipédie.\nDúfam, že moje obľúbené filmy, ako sú Divoké historky, alebo Vážený občan, si nájdu nových divákov aj vďaka slovenskej Wikipédii.\n","date":"October 1, 2026","externalUrl":null,"permalink":"/notes/wiki-miluje-film/","section":"Notes","summary":"Wikimedia Editaton - “Wiki miluje film” sa včera skončil. Tento rok editori slovenskej Wikipédie pridali 45 nových článkov na tému film, herci, seriály a všetko, čo súvisí s filmovým umením. Je to skoro 50% nárast oproti minulému roku. Samozrejme, som sa zapojil a tiež som prispel. Bola to zábava, naučil som sa veľa nových vecí pri hľadaní zdrojov a prekladaní článkov z anglickej a španielskej Wikipédie.\nDúfam, že moje obľúbené filmy, ako sú Divoké historky, alebo Vážený občan, si nájdu nových divákov aj vďaka slovenskej Wikipédii.\n","title":"","type":"notes"},{"content":"","date":"October 1, 2026","externalUrl":null,"permalink":"/tags/backup/","section":"Tags","summary":"","title":"Backup","type":"tags"},{"content":"Consolidating a digital life onto one NAS has an ugly side effect: everything now burns in the same fire. In the previous posts I described how I moved decades of files, photos and documents onto a single Synology box at home. This post is about the second half of that story - getting a copy of it out of the house, encrypted, in a way that lets me sleep.\nPicking the provider # The first lesson was that where a company keeps its servers and where it is registered are two different things. Backblaze has European data centers, but it is a Californian company, and the US CLOUD Act follows the company, not the building. For a family archive I wanted a European company in a European data center.\nPrice was the second filter, and the sticker price lies. AWS S3 Deep Archive looks like a great value - dollar per terabyte per month - until you want the family archive back, and two terabytes of restore cost $180 or more in retrieval and egress fees. Wasabi charges every object for a 90-day minimum, whether you keep it or not.\nI ended up with a Hetzner Storage Box: a German company, a data center in Falkenstein, and no traffic charges in either direction. A restore costs nothing, however big. It started as a 1 TB box for a few euros a month, and when I decided the audiobooks should go offsite too, it grew to 5 TB, for a bit over 13 euros a month.\nPicking the tool # I had just left a cloud vendor, so the question I asked every tool was: how hard is it to leave you? restic won on exactly that. The same repository format writes to SFTP, S3, Backblaze B2 and anything rclone can reach, so changing provider later is a copy, not a new upload of everything. Borg was the runner-up, but its repositories only live on hosts that run Borg itself. Choosing the tool with the narrowest exit right after escaping a vendor would have been the wrong lesson. Kopia looked nice, but it is still at version 0.x, and for twenty years of family video I want the boring, mature option.\nrestic has no scheduler of its own, so Backrest runs it on the NAS every night, and healthchecks.io sends me an email when a run fails - or when it does not happen at all.\nWhat about ransomware? The textbook answer is Object Lock, storage that cannot be overwritten. It turns out to be incompatible with deduplicating backup tools, because cleaning up old snapshots rewrites data files. Hetzner\u0026rsquo;s own daily snapshots of the box cover that case instead. They can be deleted only from Hetzner\u0026rsquo;s web console, and that login never touches the NAS.\nThe architecture in five sentences # Everything is sorted by what is at stake: the irreplaceable first (family photos and videos, documents, my notes), then what is expensive to rebuild (the ebook and audiobook libraries), and only then the rest. Each top-level folder gets its own repository, its own storage sub-account and its own passphrase, so a leaked credential exposes exactly one of them, not all ten. Everything is encrypted on the NAS with AES-256 before it leaves the house, so Hetzner stores data it cannot read, subpoena included. The NAS backs itself up, never through a laptop that happens to have the share mounted, because an alarm must not share a failure domain with the thing it watches. And the upload is throttled to 2 MiB/s, so the household internet survives it.\nThat throttle has a consequence: the first upload is the project. On my line it took days per folder and a few weeks for all of it, 2.6 TB in the end. The nightly runs afterwards take minutes. And a restore comes back about eight times faster than the upload went.\nThe laptop is a special case # The MacBook was the one machine I got wrong first. The obvious setup was Time Machine over SMB to the NAS, and I ran it that way for a while, over a wired connection. It was unusably slow. A full backup took the better part of a day, and whenever a backup was interrupted, which happens to a laptop that gets closed and carried around, Time Machine threw away its reference snapshot and spent the next fourteen hours re-reading the whole disk before it copied a single new byte. The problem is not bandwidth. Time Machine over a network share is bound by latency, one small round trip per file, and a million files on a developer\u0026rsquo;s laptop add up to hours no matter how fast the cable is.\nSo the laptop now has two layers instead of one. The first is boring on purpose: an external SSD and plain Time Machine. It is the layer for the day the disk dies, because it restores the operating system, the applications and the home folder in one go, exactly the way Apple intended. The second layer is restic again, running on the Mac itself, not on the NAS, writing over SFTP into its own share on the NAS with a long list of exclusions for things that are already safe elsewhere or can be rebuilt. Where Time Machine over SMB crawled, restic saw the same files as a stream of content-addressed blocks and never asked the server about each one.\nThe offsite part of the laptop backup is then the NAS\u0026rsquo;s job, not the laptop\u0026rsquo;s. A second restic instance on the NAS copies the blocks of that repository to Hetzner, so the Mac never talks to the cloud at all, and the same rules apply as for every other tree: encrypted before it leaves the house, its own credentials, its own alarm. If the laptop is lost or stolen, the SSD brings back the system, and the Hetzner copy brings back the work.\nWar stories, all earned # Estimates lie. My documents folder came in 93% over the size I had designed for. Measure, don\u0026rsquo;t extrapolate.\nSynology hides a trap for restic users. Deleted files go into a #recycle folder, and I excluded it in an exclude file. But in that file, a line starting with # is a comment, so the exclusion silently did nothing - while the next line, @eaDir, worked fine and made everything look correct. I confirmed it with a throwaway repository and now pass the excludes on the command line:\nrestic backup /volume1/REFERENCE --exclude \u0026#39;#recycle\u0026#39; --exclude \u0026#39;@eaDir\u0026#39; Absence must alarm. My notes vault reaches the NAS through a separate copy job from my Mac. I found out that job had quietly run exactly once, six weeks earlier - so the offsite backup was faithfully protecting a stale copy. A success notification does not catch a job that never runs. Now the NAS refuses to back up that folder if the copy is older than 36 hours, and the refusal raises the same alarm. It has already fired for real: I was travelling, the Mac slept on battery, and the Tailscale connection from the previous post cannot wake a sleeping laptop.\nThe alarm itself is proven. Over the first weeks, all three ways it can go off actually happened: a run that failed, a run that started and did not finish in time, and a run that never started. Each alert arrived on the minute.\nThe passphrase is the real risk, not the provider. Lose it and the backup is gone as surely as in a fire. So escrow is part of the deliverable: the password manager, plus a printed sheet with hand-written passphrases, tested by typing one from paper on another machine and opening a repository with it.\nA credential prompt is only ever typed into a real terminal. Once, a sub-account password ended up in an AI chat transcript instead of an SSH prompt. The damage was limited to one folder by design, and I changed the password the same evening. The design assumption \u0026ldquo;credentials leak eventually\u0026rdquo; paid its rent.\nDeduplication has pleasant surprises. When I unzipped a few hundred audiobook archives, I expected to upload about 250 GB of new data. restic uploaded 72. Audio does not compress, so the bytes inside the zip files were almost the same as the extracted files, and restic recognized them. It also means reorganizing folders later costs almost nothing.\nAnd finally, restore drills. Every folder except the newest one has already been restored from the cloud at least once, and a single lost document comes back in about three seconds. That number, not the upload speed, is what the whole project buys.\nNext in this series: taming the online storages.\n","date":"October 1, 2026","externalUrl":null,"permalink":"/posts/2026-10-01-offsite-backups-with-restic-and-hetzner/","section":"Posts","summary":"Consolidating a digital life onto one NAS has an ugly side effect: everything now burns in the same fire. In the previous posts I described how I moved decades of files, photos and documents onto a single Synology box at home. This post is about the second half of that story - getting a copy of it out of the house, encrypted, in a way that lets me sleep.\nPicking the provider # The first lesson was that where a company keeps its servers and where it is registered are two different things. Backblaze has European data centers, but it is a Californian company, and the US CLOUD Act follows the company, not the building. For a family archive I wanted a European company in a European data center.\n","title":"Catching up: Offsite Backups That Let Me Sleep","type":"post"},{"content":"","date":"October 1, 2026","externalUrl":null,"permalink":"/categories/devops/","section":"Categories","summary":"","title":"Devops","type":"categories"},{"content":"","date":"October 1, 2026","externalUrl":null,"permalink":"/tags/hetzner/","section":"Tags","summary":"","title":"Hetzner","type":"tags"},{"content":"","date":"October 1, 2026","externalUrl":null,"permalink":"/tags/restic/","section":"Tags","summary":"","title":"Restic","type":"tags"},{"content":"","date":"October 1, 2026","externalUrl":null,"permalink":"/tags/synology/","section":"Tags","summary":"","title":"Synology","type":"tags"},{"content":"Občianske združenie Istros, alias Spoločnosť priateľov Grécka a Cypru na Slovensku ktoré sme tento rok založili, má konečne website, ktorý nie je statický. Pôvodný website mal neprekonateľnú cenu, bol zadarmo, ale technológia použitá pre jeho zostavenie viac-menej vylučovala jednoduché udržiavanie a pridávanie obsahu iným ako mnou, alebo niekým, kto je doma v oblasti DevOps statických websitov a má prístup ku všetkým komponentom.\nVýbor Združenia rozhodol, že ideme preportovať obsah na WordPress tak, aby aj ostatní členovia mohli prispievať obsahom, a vytvárať nové príspevky.\nVčera sa to stalo, a https://www.istros.eu/ je online.\n","date":"September 29, 2026","externalUrl":null,"permalink":"/notes/istros-ma-opat-website/","section":"Notes","summary":"Občianske združenie Istros, alias Spoločnosť priateľov Grécka a Cypru na Slovensku ktoré sme tento rok založili, má konečne website, ktorý nie je statický. Pôvodný website mal neprekonateľnú cenu, bol zadarmo, ale technológia použitá pre jeho zostavenie viac-menej vylučovala jednoduché udržiavanie a pridávanie obsahu iným ako mnou, alebo niekým, kto je doma v oblasti DevOps statických websitov a má prístup ku všetkým komponentom.\nVýbor Združenia rozhodol, že ideme preportovať obsah na WordPress tak, aby aj ostatní členovia mohli prispievať obsahom, a vytvárať nové príspevky.\n","title":"","type":"notes"},{"content":"Seven devices, two of them NAS boxes, and a laptop that travels with me. For years, reaching any of them from outside the house was a small project every time. In July 2026 I put all of them on one private network, and the day every machine got one name that works from anywhere, half of my runbooks got shorter.\nWhy a mesh VPN # My home fleet is not big, but it is spread out: two MacBooks, an iPhone, an iPad, a Mac mini that is always on and serves as a small home hub, and two Synology NAS boxes, an old one and a new one.\nBefore, the reality looked like this. Names like nas.local worked only at home - they come from mDNS, which never leaves the local network. Scripts had LAN IP addresses hardcoded in them. Remote access meant Synology\u0026rsquo;s QuickConnect, or thinking about port forwarding on the router, which always made me a bit nervous. And many of my runbooks had two variants: one for when I am at home, one for when I am not.\nTailscale is a mesh VPN built on WireGuard. Every device gets a stable address and can see all the others, no matter which network it is on. The coordination server only helps the devices find each other and exchange keys; the data itself flows directly between them, over the LAN when they are both at home. The Macs and the iPhone were on it first, and both NAS boxes joined on one busy day in July.\nThe doctrine that came out of it # The most important decision was not a technical one. Every machine now has one name that is valid everywhere, and that name is the default in every document and script I write. The LAN name and the IP address are fallbacks only. No more \u0026ldquo;am I at home?\u0026rdquo; branching. It also fixed a real class of failures: scripts and AI agents running in a shell on my laptop could not reach the NAS, because they relied on names that only resolve at home.\nThe free tier is enough. MagicDNS (the short names), Taildrop (sending files between your own devices), exit nodes and subnet routing are all included. The paid tiers sell enterprise plumbing - user provisioning, device management, flow logs - that a household does not need. I tried the business trial for the custom domain, then settled on the free plan.\nOne neat privacy detail: the name of your tailnet is random on purpose. If it were derived from your domain, it would end up in the public certificate-transparency logs, and anyone could see whose network it is. A random name tells them nothing.\nTraps for the Synology owner (all hit personally) # Synology and Tailscale work well together once you know where the traps are. I stepped into every one of these.\nOn DSM 7, packages run in a sandbox. Without a small boot task, running as root, that gives the package access to the TUN device, only inbound connections work. You can reach the NAS, but the NAS cannot reach anything over the tailnet, and nothing tells you so. The older DSM 6 has no such problem. And once the TUN device is on, tailnet traffic goes through the DSM firewall, so the firewall needs a rule that allows the Tailscale address range (100.64.0.0/10) - otherwise you lock yourself out the moment you are away from home.\nSynology\u0026rsquo;s Package Center offered a Tailscale version about two years old. The fix is to download the package from Tailscale directly and install it manually, but a manually installed package never updates itself. That makes it a recurring chore, worth a calendar entry.\nAnd never upgrade DSM over a Tailscale connection. When the NAS restarts in the middle of the upgrade, your connection goes with it.\nTwo more for the Mac. The Tailscale app does not put its command-line tool on the PATH, and symlinking the binary into /usr/local/bin crashes it, because the app then cannot find its own bundle. A shell alias works:\nalias tailscale=\u0026#34;/Applications/Tailscale.app/Contents/MacOS/Tailscale\u0026#34; Taildrop is push-only: you always send from the device that has the file, because a phone runs no services you could pull from. And the target needs a trailing colon, which I forgot more than once:\ntailscale file cp report.pdf iphone: Roads deliberately not taken # Not everything Tailscale can do made it in.\nAn exit node would route all my traffic through home when I sit on some hotel or café wi-fi. The always-on Mac mini is the obvious candidate, but I parked the idea. It would be capped by my home upload speed anyway.\nTailscale Funnel can publish a service from your tailnet to the open internet. I looked at it for sharing my ebook libraries with family, and rejected it. Family will not install a VPN, and Funnel puts no login gate in front of the service. The libraries now sit behind Cloudflare Access instead, where a one-time code sent to an approved email address opens the door. Tailscale is for my machines, not for my audience.\nA subnet router would expose a whole local network to the tailnet, including devices that cannot run Tailscale themselves. I keep that one in reserve for a possible second location, where a small mini PC would make remote access feel the same as being on site.\nIf I had to name one lesson from all this: the value was never the VPN itself. It was one name per machine that works everywhere. Everything else followed from that.\nNext in this series: offsite backups with restic and Hetzner.\n","date":"September 29, 2026","externalUrl":null,"permalink":"/posts/2026-09-29-tailscale-everywhere/","section":"Posts","summary":"Seven devices, two of them NAS boxes, and a laptop that travels with me. For years, reaching any of them from outside the house was a small project every time. In July 2026 I put all of them on one private network, and the day every machine got one name that works from anywhere, half of my runbooks got shorter.\nWhy a mesh VPN # My home fleet is not big, but it is spread out: two MacBooks, an iPhone, an iPad, a Mac mini that is always on and serves as a small home hub, and two Synology NAS boxes, an old one and a new one.\n","title":"Catching up: Tailscale Everywhere","type":"post"},{"content":"","date":"September 29, 2026","externalUrl":null,"permalink":"/tags/homelab/","section":"Tags","summary":"","title":"Homelab","type":"tags"},{"content":"","date":"September 29, 2026","externalUrl":null,"permalink":"/tags/networking/","section":"Tags","summary":"","title":"Networking","type":"tags"},{"content":"","date":"September 29, 2026","externalUrl":null,"permalink":"/tags/tailscale/","section":"Tags","summary":"","title":"Tailscale","type":"tags"},{"content":"Last weekend 25th to 27th of September, members of Wikimedia Slovensko met in Dubnica nad Váhom. It was great to meet the fellow Wikipedians in the flesh again (Matej, Patrik and Filip), and to meet Kormi in 3D for the first time.\nIt was mainly a planning, coordination and brainstorming meeting, but part of the programme happened outdoors, with cameras. By Sunday the town\u0026rsquo;s 18th-century Calvary had its own photos on Wikimedia Commons, a record on Wikidata and the start of a Slovak Wikipedia article. The local Jewish cemetery gained a set of new photographs too. That weekend is a good small example of what this whole thing is about.\nWhy two Wiki in the title and what is Wikimedia? # Pretty much everybody knows that Wikipedia is a free online encyclopedia that anyone can read and anyone can edit. Jimmy Wales and Larry Sanger founded it in 2001. Today it exists in 348 language editions. The English one alone has more than 7.2 million articles, and the Slovak Wikipedia has about 261,000. Nobody is paid to write it. The articles come from volunteers, and every statement is meant to be backed by a published, reliable source. Every edit is public and can be traced in the page history.\nWhat is Wikimedia, and how does it relate to Wikipedia? # \u0026ldquo;Wikimedia\u0026rdquo; is the name of the family around Wikipedia, and it means three things:\nThe Wikimedia Foundation, a non-profit in San Francisco, founded in 2003. It runs the servers, develops the software (MediaWiki) and hosts Wikipedia and its sister projects. It does not write or edit the content; the volunteer communities do. The Wikimedia movement: the volunteers who write, photograph, check and discuss, organised per language and per project. Local organisations such as Wikimedia Slovensko (website, in Slovak; English page on Meta), a Slovak civic association (občianske združenie), known internationally as Wikimedians of Slovakia. They organise events, workshops, photo walks and competitions, and bring Wikipedia to schools, libraries and museums. In short: Wikipedia is the best-known project; Wikimedia is everything that makes it and its siblings possible.\nIt is not just an encyclopedia: the sister projects # There are many wiki things under the Wikimedia umbrella. They complement each other and address different aspects of free knowledge sharing.\nWikimedia Commons: a free media library of more than 148 million photos, maps, recordings and videos. Our Dubnica photos went here. Wikidata: a shared database of facts that people and machines can both read, with over 120 million entries. Wikipedias in every language can draw dates, coordinates and links from it. Wiktionary (Slovak: Wikislovník): a dictionary in many languages. Wikisource (Slovak: Wikizdroje): a library of free source texts. Wikiquote (Slovak: Wikicitáty), Wikibooks (Slovak: Wikiknihy), Wikivoyage, Wikispecies, Wikiversity and more. Wikipedia: the foundation the AI boom stands on # The best-known large language models learned to write in part from Wikipedia. Where the training recipes are published, they say so plainly:\nGPT-3 (Brown et al., 2020, Table 2.2) sampled Wikipedia more often than the rest of its data. Wikipedia was passed through the training 3.4 times, compared with less than half a pass (0.44) for the general web crawl. The authors did this because they viewed it as higher-quality data. LLaMA (Touvron et al., 2023) built its model \u0026ldquo;using publicly available datasets exclusively\u0026rdquo; and used Wikipedia dumps in 20 languages. Two things make Wikipedia so valuable for this. The first is quality: its text is sourced, edited, discussed and corrected by people. The second is licence: its text is published under CC BY-SA 4.0, an open licence that explicitly allows reuse on two conditions: credit the authors and share alike. Much of the rest of the web carries no such permission, and whether it may be used for training is contested. Wikipedia is one of the largest bodies of text whose reuse is plainly allowed.\nThe Wikimedia Foundation put it bluntly in November 2025: \u0026ldquo;AI cannot exist without the human effort that goes into building open and nonprofit information sources like Wikipedia.\u0026rdquo; It asks AI companies for two things in return: to credit Wikipedia and its volunteers, and to support it financially, for example through the paid Wikimedia Enterprise service.\nThe other side of that coin: models are only as good as what people write. If fewer people edit Wikipedia, the source that the AI world depends on gets thinner. Every sourced sentence you add improves both the encyclopedia and the tools built on it.\nFour reasons to start editing # Some work is simply useful. Nobody pays for it, and someone still has to do it: a sourced paragraph about a village church, a photo of a monument before it crumbles, a date that is finally correct. Going part-time gave me something I had not had for decades: a choice about a big part of my week. I could have filled it with more paid work. Instead I put a fair share of it here. Not because I have nothing else to do, but because I think this is where those hours count. If you also have some say over where your time goes, this is worth a thought.\n1. Your knowledge is missing, and your edit counts. The Slovak Wikipedia has about 261,000 articles, but only around 1,200 users were active in the last 30 days. Your town, your field of study, the local church, a forgotten scientist: often nobody has written about them yet. Until last weekend, the Calvary in Dubnica had no article at all. It will have a proper one soon.\n2. You learn skills that matter everywhere. Finding sources, telling a reliable source from a weak one, writing neutrally and briefly, and accepting criticism of your text. That is research and media literacy in practice, and in an age of AI-generated text it is worth more than ever.\n3. What you write reaches people, and machines. Wikipedia is one of the most visited websites in the world. As the section above shows, what is written there also shapes what AI assistants answer. A good paragraph about your region will be read, and reused, long after you write it.\n4. You don\u0026rsquo;t have to write a whole article, and you are not alone. You can start with a typo fix, a photo from your phone uploaded to Commons, or a missing fact on Wikidata; those two work the same in any language. Wikimedia Slovensko runs events and training in Slovakia. Every Wikipedia also has a place where experienced editors answer newcomers\u0026rsquo; questions: the Teahouse on the English one, and Kaviareň (\u0026ldquo;the café\u0026rdquo;, in Slovak) on the Slovak one. If you read Slovak, go to the second: that is where a new pair of hands makes the biggest difference.\nHow to start # Create an account on Wikipedia and fix one thing you know is wrong. One account works in every language. (If your first language is a smaller one, your national Wikipedia needs you the most. The Slovak Wikipedia has around 1,200 active editors. The English and Spanish ones are doing just fine, although they are still a good place to share local knowledge that nobody outside your region has written up.)\nIf you read English, the introduction tutorials walk you through your first edits, and the Teahouse is there for questions. If Slovakia is what interests you, WikiProject Slovakia on the English Wikipedia gathers the articles about the country and the people who look after them. And wherever you live, there is probably a Wikimedia group near you: the list of Wikimedia affiliates has the national chapters and user groups.\nIf you read Slovak, come and find us. Wikimedia Slovensko is a small, entirely volunteer association. Its contact page has the e-mail address and the mailing lists, and news goes out on Facebook. The yearly photo competitions, Wiki miluje pamiatky (Wiki Loves Monuments) and Wiki miluje Zem (Wiki Loves Earth), make an easy first project with a clear goal. Membership costs 10 euros a year, 5 for students, and if you pay income tax in Slovakia you can also assign 2% of it to the association. The easiest way in, though, is simply to write, or to catch one of us at the next meetup.\n","date":"September 28, 2026","externalUrl":null,"permalink":"/posts/2026-09-28-a-wiki-wiki-wikend/","section":"Posts","summary":"Last weekend 25th to 27th of September, members of Wikimedia Slovensko met in Dubnica nad Váhom. It was great to meet the fellow Wikipedians in the flesh again (Matej, Patrik and Filip), and to meet Kormi in 3D for the first time.\nIt was mainly a planning, coordination and brainstorming meeting, but part of the programme happened outdoors, with cameras. By Sunday the town’s 18th-century Calvary had its own photos on Wikimedia Commons, a record on Wikidata and the start of a Slovak Wikipedia article. The local Jewish cemetery gained a set of new photographs too. That weekend is a good small example of what this whole thing is about.\n","title":"A Wiki Wiki Wikend","type":"post"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/tags/ai/","section":"Tags","summary":"","title":"Ai","type":"tags"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/tags/commons/","section":"Tags","summary":"","title":"Commons","type":"tags"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/categories/general/","section":"Categories","summary":"","title":"General","type":"categories"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/tags/wikidata/","section":"Tags","summary":"","title":"Wikidata","type":"tags"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/tags/wikimedia/","section":"Tags","summary":"","title":"Wikimedia","type":"tags"},{"content":"","date":"September 28, 2026","externalUrl":null,"permalink":"/tags/wikipedia/","section":"Tags","summary":"","title":"Wikipedia","type":"tags"},{"content":"I have always been a pack rat when it came to digital assets. I didn\u0026rsquo;t like the idea of deleting files. What if I want to come back to them later? After all, they don\u0026rsquo;t really take almost any physical space compared to paper books (certainly not now, in the age of multi-terabyte hard drives and the cloud). So what I did - I kept archiving them.\nIt started in the late \u0026rsquo;80s and the \u0026rsquo;90s with floppy disks, eventually migrated to external hard drives, CDs, DVDs and with the ascent of the cloud they ended up in a variety of various storage solutions.\nAs I replaced computers and got rid of the older ones, what I usually did was to copy everything that was on the old machine to the backup disks, transfer a subset of the files to the new one, and continue.\nSo after almost 40 years of digital life I was left with two NAS boxes, 23 external disks, six clouds and eight dead applications holding real documents. A huge portion of the files were duplicates, but I didn\u0026rsquo;t really know which files, or on which disks. In 2023 I started a project to fix it. The project failed - and that failure taught me the shape of the actual solution.\nThe umbrella that collapsed # In 2023, while still working full time, I started a very ambitious side project codenamed \u0026ldquo;big declutter\u0026rdquo;. One project to find anything again and to answer the nagging question: I\u0026rsquo;m sure I have that file somewhere. But where? And how do I find it? It missed its yearly horizon three times.\nIn 2026 I realized it wasn\u0026rsquo;t a project at all - it was (in my Obsidian vault lingo) area work wearing a project costume. It required a different approach and a much larger time allocation than a side project could provide. Dissolved, not finished: the architecture became a standing Data Map, the chores became chores, the real work became real projects.\nI started with the Data Map: a table of content domains against the ways data moves and how it is kept, where each cell goes from not covered to partial to done. Nothing \u0026ldquo;closes\u0026rdquo; it - that\u0026rsquo;s the point.\nThe Data Map split the space of files in various archives semantically: \u0026ldquo;documents\u0026rdquo; belonging to different categories, like legal, identity, finance and so on. Work memories, work archives. Media - both created and collected - like family photos, family videos vs purchased ebooks and audiobooks. My meme collection. Social media exports and takeouts. Old notes. Secrets (passwords, identities, access codes). Movie and music collections. Lots of source code. Web clippings.\nThey were physically living on 23 external disks, 2 NAS boxes (one of which required an upgrade and migration) and 6 different cloud services (Google Drive, AWS, Tresorit, OneDrive, iCloud and Dropbox), and what made the situation worse is that some part of the information was locked in old application formats that needed rescue and everything really needed cataloguing and deduplication.\nWhat replaced it # I started with a disk catalog of all external disks, NAS volumes as well as the cloud services. That was holding information about every file, its metadata and, in most cases, the SHA-1 hash of the content. This was the driver of everything on the old Synology moving to the new NAS, checksum-verified, into a proper filing structure.\nWith a disk catalog and every file hashed, the question \u0026ldquo;do I have this file?\u0026rdquo; could get answered without mounting anything.\nA dedicated application, the \u0026ldquo;directory of things\u0026rdquo;, is how this question gets answered: it searches across 2.5 million items (files, books, notes, people). It deliberately owns nothing and only knows where things live. It lives happily on a Mac mini at home, accessible only via my tailnet.\nThe directory of things, showing my books by Dominik Dán: 44 titles and every format I own of each.\nI have already evacuated one paid cloud (sorry, Tresorit, you worked great and were European - but the lack of an API and the cost/feature ratio were decisive). OneDrive, AWS S3 and Dropbox are in the process of being emptied or migrated, and by next year I will be down to iCloud and Google.\nThe media library, the photo hub and the ebook pipeline each give one collection a single curated home.\nI made a proper offsite backup, hosted on a Hetzner Storage Box, using restic, with client-side encryption and per-domain collection, separately restorable - it is the piece that makes any deletion safe. It gets its own post later in this series.\nVault publishing turns a set of curated notes into something family and readers can actually see, this blog included.\nThis very post, being written in Obsidian.\nThe rules that made it manageable - lessons learned # Along the way I picked up a handful of rules. The first is about where the truth lives: the catalogs own the facts, the tools I browse with own nothing, and data flows only one way, from the catalog to the view. The second is about effort. How much care a collection gets depends on how irreplaceable it is, and size barely matters. Family photos that exist nowhere else get more protection than a shelf of ebooks I could buy again.\nThe third rule keeps me from doing damage: nothing gets deleted from a cloud until the NAS has a stated backup plan for that kind of data. A rescue must never leave me with fewer copies than before. The fourth one I learned the hard way. Before retiring a disk, sweep its trash folders first. On one disk, the hidden .Trashes folder held 9,204 files.\nAnd the last one is the lesson of the whole story: projects end, areas don\u0026rsquo;t. Once I named which was which, half the battle was won.\n","date":"September 24, 2026","externalUrl":null,"permalink":"/posts/2026-09-24-reorganizing-my-digital-life/","section":"Posts","summary":"I have always been a pack rat when it came to digital assets. I didn’t like the idea of deleting files. What if I want to come back to them later? After all, they don’t really take almost any physical space compared to paper books (certainly not now, in the age of multi-terabyte hard drives and the cloud). So what I did - I kept archiving them.\nIt started in the late ’80s and the ’90s with floppy disks, eventually migrated to external hard drives, CDs, DVDs and with the ascent of the cloud they ended up in a variety of various storage solutions.\n","title":"Catching up: Reorganizing My Digital Life","type":"post"},{"content":"","date":"September 24, 2026","externalUrl":null,"permalink":"/tags/data-hygiene/","section":"Tags","summary":"","title":"Data-Hygiene","type":"tags"},{"content":"","date":"September 24, 2026","externalUrl":null,"permalink":"/tags/nas/","section":"Tags","summary":"","title":"Nas","type":"tags"},{"content":"Plain markdown files turned out to be the best possible interface between a decade of notes and a language model. No API, no export, no connector, no sync service in the middle: the agent opens the folder and reads it, the same way I do. This post is what happened once I let it.\nThe setup # There is a CLAUDE.md file at the root of my vault. It is twenty-nine lines long, and the last three of them say this:\nThis vault is managed exclusively through Anthropic Claude (Cowork, Claude Code, API). Use all available features: skills, scheduled tasks, MCP tools, memory, subagents. No other AI agents are active on this vault.\nThat is not brand loyalty, it is a maintenance decision. The instructions, the memory files, the tag taxonomy, the frontmatter standards and the session conventions are all written for one harness. Two agents with two sets of conventions produce a vault that neither of them can keep tidy.\nThe second half of the setup is that sessions are anchored at both ends, and that turned out to matter more than any individual agent.\nWhat a session leaves behind # At the start of a session, a hook reads the working directory and resolves it to a vault note: a project note under notes/1-proj/, or a forge note for standing work that has no end date. The agent\u0026rsquo;s first line back to me is the anchor it resolved, so if it guessed wrong I find out in the first second rather than three hours in. Work that cannot be anchored to a note does not start.\nAt the end I run one command, and it writes to up to three places.\nThe project note gets the full record. A dated status callout: where we are, the plan in one paragraph, every file touched with a one-line description of what changed in it, and the single most important next action. These stack newest-first and nothing is ever overwritten, so the note grows into a reverse-chronological history of the project. Each callout is stamped with a block anchor, something like ^status-2026-09-22-2319.\nIf the project has a STATE note beside it, that one gets refreshed in place instead of appended to. The distinction is the entire trick. The project note is the commit history; the STATE note is the working tree. It holds no history at all, anything the session obsoleted moves to a superseded table or gets deleted, and every fact left in it is supposed to be true today. That is the file the next session reads, instead of replaying nine months of callouts.\nToday\u0026rsquo;s journal entry gets the least of all: a heading, two lines, and a deep link into the callout. Verbatim, from Tuesday:\n### [[m-vault-publishing]] - three Catching-up posts published Parts 3, 4 and 5 of Catching-up went live, plus two stream notes; pasted images are now live-proven end to end, leaving code blocks as the last unpublished Phase 2 path. -\u0026gt; [[m-vault-publishing#^status-2026-09-22-2319|full status ↗]] That is deliberately not a summary I have to keep current. It is an index entry. The journal answers \u0026ldquo;what did I actually do that day\u0026rdquo;, one line per project, and the link jumps to the detail rather than duplicating it.\nThe last thing in the callout is a copy-ready continuation prompt: the working directory, the files to read first in a sensible order, where we left off, the next action. Next time I open a session I paste that block and the agent is caught up in one message. This post started as exactly such a block, pasted in cold, ending with a line that reads \u0026ldquo;New information I have today:\u0026rdquo; and a blank for me to fill in.\nSo the vault is both the thing being worked on and the memory of the work. When I come back three weeks later I do not reconstruct context by scrolling a chat history, which the agent cannot read anyway. I read the note.\nOne rule holds the whole mechanism together: I end the session, never the agent. It ran the reconcile on my behalf once, unasked, immediately after finishing a task that was not the session. That cost 15 to 20 per cent of the session\u0026rsquo;s tokens re-reading what it had just written. Now it is in the instruction file, in capitals.\nThe staff # The pattern that emerged was not one assistant, it was a roster of named, single-purpose agents with written job descriptions. A PDF surgeon who splits textbooks into lessons. An accountant who reconciles bank statements against invoices. A gardener who audits tags and hunts orphan notes. A librarian for the clippings inbox. An archivist for the NAS. A chief of staff who does no work at all and only delegates.\nEach one is a markdown file with YAML frontmatter. Helga the Gardener, in full, minus her personality prompt:\n--- name: Helga the Gardener model: sonnet description: |- Vault curator agent that tends Miro\u0026#39;s digital knowledge garden. Audits tag consistency, enforces frontmatter standards, maintains MOCs, suggests note relocation, and identifies orphans. Works in audit-then-fix mode with explicit confirmation before changes. tools: [Read, Write, Edit, Bash, Grep, Glob] allowed_commands: [\u0026#34;uv run python3\u0026#34;] color: \u0026#34;#92400E\u0026#34; --- Two lines there matter more than the rest. tools: and allowed_commands: are the leash. Helga can read, write and run Python; she cannot call anything else. The description is not decoration either, it is the routing table: it decides which agent gets woken up for which request.\nThey accumulated over four months, not in one burst. Sergio the PDF Surgeon on 7 April 2026, Fred the Accountant and Helga two days later, a finance advisor on the 15th, Marcel the Librarian in June, Larry the Chief of Staff in July, Otto the Archivist at the end of July.\nAnd one got fired. Lorenzo, my Italian tutor, was cancelled on 12 April after five or more rule violations: truncating my corrections so I never saw half of them, running a shell command he had been explicitly forbidden to use, writing to paths that had been retired months earlier. The journal entry for that day has a heading that reads, in full, \u0026ldquo;Fired Lorenzo\u0026rdquo;. The main agent took over the lessons.\nThe difference between the Lorenzo who was fired and the Lorenzo who came back is worth spelling out, because it is the actual lesson. The first one was a subagent: spun up inside a session out of instructions I typed at the time, handed the job in the prompt, and gone the moment the session ended. Nothing about him persisted. When he broke a rule, the only available fix was to explain the rule again next time, to a fresh copy that had never heard it. That is how you reach five violations of the same rule without anything improving.\nThe second one, dated 4 June, is a file on disk, exactly like Helga above. The job description, the trigger phrases, the tool list, the lesson protocol and the file-naming rules all live in it permanently, and the specific failures are written into it by name. There is a fixed reply template, headed \u0026ldquo;Non-negotiable reply contract\u0026rdquo;, so a correction cannot be quietly truncated. And there is a line that reads: Never run find; use ls on the exact path or fd scoped. He still has Bash, so that is a written rule rather than a locked door, but it now sits in the one document he is guaranteed to read before every single lesson. The typed-in version was never guaranteed to be read at all.\nWhich is the honest version of managing AI staff: it includes terminations, and occasionally it includes rehiring the same guy, once you work out that the problem was the job description and not the worker.\nWhat actually got done # A legacy Notion workspace pulled down in full: 10,237 pages, 246,895 blocks, about 36 hours of wall clock at the API\u0026rsquo;s own pace. Then triaged by AI, 1,426 units of it, into 229 keep and 1,197 prune. A cheap model handled 1,355 of those and escalated 71 to a stronger one. Total API cost for the triage, $6.22.\nA family documentation site, harvested out of Notion and republished page by page, which is the reason the publishing tooling exists at all.\nThis blog. The post you are reading was written in Obsidian, staged into the Hugo site by a tool the agent and I built together, reviewed in a local Hugo instance, and published by me.\nAnd the chores. Filing runs, catalog audits, frontmatter sweeps, tag weeding: the work that was always theoretically possible manually and therefore never happened.\nThen the larger ones, which are the reason the staff exists at all.\nA directory of everything I own, queryable: thousands of ebooks, 2.5 million files, thousands of notes and hundreds of people (writers, actors, directors, network contacts), assembled from 28 separate catalogs and refreshed nightly. My favourite incident in the whole setup belongs to this one. A safety guard that refuses any sync which would delete more than a fifth of a catalog froze the pipeline for five consecutive nights. It was right: a media tree had genuinely been moved to a different share, and the shrink was real. The cheap heuristic that predicted which catalog would trip was wrong, because churn hides behind net growth. Getting the true answer meant replicating the store\u0026rsquo;s own identity logic across all twenty-seven of the others.\nMigrating an entire NAS estate onto new hardware. 970 audiobook files, 238.90 GiB, retired only after every title was proven present at the destination by content hash rather than by name. Of thousands of ebooks, just 61 existed nowhere else, and of those three were worth keeping. 86,777 files sorted into staging buckets, of which 16,449 turned out to be bytes that already lived somewhere else. The session that went wrong here produced the most useful rule in the vault: every incorrect number came from treating a filename as an identity. Match on content, search every catalog, query the live system and never a snapshot. Which is git\u0026rsquo;s core idea - a thing is identified by the hash of its bytes, not by the label on the box - rediscovered the long way round ;-)\nA deduplicated meme archive, which sounds like a joke and is the cleanest piece of software in the collection. Content-addressed, every image citable by its md5, published, 294 tests. The \u0026ldquo;newest arrivals\u0026rdquo; wall was specified, built test-first and deployed in a single evening. It is internal, accessible only through Tailnet, but I have even added a public share interface (redirected via Cloudflare) to send especially good ones to my friends around the globe - this one, say, or this one. Note the AI-generated text and classification.\nAnd Feri, who is the only agent named after a real person. František Kovács, Feri, is my actual personal trainer, a man I worked with for over two years and who taught me everything I know about weightlifting. Feri 2.0, built in late spring 2026, replicates the single function the design note names as the point of him, \u0026ldquo;the correction the real Feri used to provide in person\u0026rdquo;. He reads the export from my lifting app and the Apple Watch dailies, locates me in the week\u0026rsquo;s plan, and prescribes the next concrete session. He is deliberately firm about recovery: a recovery flag downgrades the day to zone 2 or mobility work automatically. I can override it, which is the design working, because overriding is then a decision I make on purpose instead of a default I drift into. So far it has kept me clear of both injuries and overtraining.\nEach run writes a gym card, updates the state note that serves as his memory, and drops one line into the day\u0026rsquo;s journal. There are almost a hundred of those cards now, the first from the start of the summer and the most recent this morning. That is the part I actually care about. Not that the agent is clever, but that I have not stopped.\nThe whole health-data flow, including Apple Watch, workout-tracking app (I am using Hevy.com now) and the Health.md app, is quite interesting and probably deserves a dedicated post.\nWhat I learned driving it # Framework overlays age badly, thin skills age well. In March 2026 I adopted a whole workflow framework on top of Claude Code, built around the premise that context rot in a 200k window was the central problem. By June the context windows were 1M tokens, the harness had grown native equivalents for everything the framework provided, and I retired it (it was GSD, if you care). The three small custom skills written in the same month all survived and are still in daily use. The decision record is dated 10 June 2026, and the line I keep coming back to is that an overlay competes with the harness for control, while a skill composes with it.\nHard rules beat good intentions, and they have to be written down. Mine are absolute and they are in the instruction file, not in my head: the agent never commits, never pushes, never deletes anything it did not create in the current session. Every one of those rules exists because it was broken once. The delete rule cost me a Time Machine restore.\nDelegated work gets adversarially reviewed. One agent implements from a written spec, a second one is pointed at the result and told to tear it apart. On the last significant change to the publishing pipeline that produced ten confirmed findings, all fixed before anything shipped. It costs a second pass and it is the single highest-value habit in the whole setup.\nTrust is per-task and revocable. See: Lorenzo. And I am still the only one with publish rights, in every repo, on purpose.\nNext: thirty years of digital sprawl, the decluttering project that failed three years running, and what replaced it.\n","date":"September 23, 2026","externalUrl":null,"permalink":"/posts/2026-09-23-obsidian-plus-claude/","section":"Posts","summary":"Plain markdown files turned out to be the best possible interface between a decade of notes and a language model. No API, no export, no connector, no sync service in the middle: the agent opens the folder and reads it, the same way I do. This post is what happened once I let it.\nThe setup # There is a CLAUDE.md file at the root of my vault. It is twenty-nine lines long, and the last three of them say this:\n","title":"Catching up: Obsidian + Claude","type":"post"},{"content":"","date":"September 23, 2026","externalUrl":null,"permalink":"/tags/claude/","section":"Tags","summary":"","title":"Claude","type":"tags"},{"content":"","date":"September 23, 2026","externalUrl":null,"permalink":"/tags/obsidian/","section":"Tags","summary":"","title":"Obsidian","type":"tags"},{"content":"","date":"September 23, 2026","externalUrl":null,"permalink":"/tags/pkm/","section":"Tags","summary":"","title":"Pkm","type":"tags"},{"content":"","date":"September 23, 2026","externalUrl":null,"permalink":"/categories/technology/","section":"Categories","summary":"","title":"Technology","type":"categories"},{"content":"This is a history of three years - from bookmarking ChatGPT articles to an AI-managed knowledge base; with a certification in the middle and one embarrassing self-assessment along the way.\nSpectator to User (2023) # I still remember my first interactions with ChatGPT (via the web, using the free version) sometime in early 2023. I wanted to have an episode guide of an excellent HBO series called Patria, a story of a Basque family during the ETA years. So I asked for it, and what ChatGPT produced was completely, utterly, unbelievably hallucinated: 12 episodes (the series has 8), a made-up story, randomly assigned actors, two thirds of them non-existent. One huge hallucination. I did not keep the transcript, but I remember it clearly. It was very disappointing, and my conclusion was: well, this is fun, but useless.\nFor most of 2023 (my vault holds the first ChatGPT bookmarks) I was mostly reading about it, not working with it. Then in October 2023 I started a GitHub Copilot trial: the first AI tool that actually touched my work. It was a real improvement and made autocomplete surprisingly usable. It still hallucinated, made-up API calls and function parameters were the norm, but the speed-up was no longer ignorable. So Copilot became a paid line item through 2024, bringing with it YouTube guides, later even the certification course.\nKicking the tires (2024) # In 2024 I was still working for Pivotree, and one area where Copilot became really useful and really good was infrastructure code. The narrower the domain, the better were the results. Copilot and Terraform were something that worked together very well, and it significantly helped processing and consuming log files and identifying a production problem. Kubernetes upgrade sucked much less, and processing large YAML files and cloud formation was significantly more bearable. The company\u0026rsquo;s position on using AI tools was evolving - we didn\u0026rsquo;t have any enterprise-level subscription or corporate tools at that time yet.\nI became a freelancer in the summer of 2024, but my first contract was with a financial institution that had very strict security guidelines, so there was little space there for using AI. They even tried to force me to use the corporate Windows laptop, locked down - something that I despised with passion. I still remember 2 JIRA tickets, three days wait and four people involved in order to get Visual Studio Code installed on that machine. Not surprisingly, the contract did not last long, and I made sure that banks and other financial institutions that insist on corporate notebooks are on my \u0026ldquo;sorry not interested\u0026rdquo; client list.\nShopping phase (2025) # Being a freelancer who is not under financial pressure to find and accept the next contract is a very enviable position to be in. So I was very picky when searching for my next assignment; but eventually I found a startup that needed to convert its existing infrastructure into IaC. It was a great match and a great application area for really using language models. In addition to the GitHub Copilot subscription, I started to pay for Cursor and I was very impressed how much it improved my daily workflow.\nI was aware of the new kid on the block, called Claude, but I was resisting the temptation for some time. My notes from that period reflect it. I was trying to justify to myself sticking with something that worked quite well, rather than jumping into completely new territory (especially when the new territory had a pretty big price tag) - notes about Cursor vs Claude Code comparisons piling up in the mid-2025 watchlists (\u0026ldquo;Why I QUIT Claude Code for Cursor\u0026rdquo; et al.)\nSometime around June 2025 I started to use MCPs, and after buying a new M4 MacBook Pro with 48 GB of RAM, to experiment with Ollama and local models.\nCursor did deliver, but also made me aware of its limitation: the ability to control the context and steer the code generation the right way. The recurrence of falling into the same traps and repeating the same mistakes over and over was what made me look around and start reading about Claude.\nCommitment phase (2026 - Hello Anthropic, take my money) # I started in December 2025 with Claude Code, properly this time - reading about it, taking courses, watching tutorials.\nUnlike with Cursor, the key discovery with Claude was that I could use it not only for writing code, but for everything other than writing code, especially for my notes. The moment is captured on 2026-02-27, verbatim from the journal: \u0026ldquo;I\u0026rsquo;ve started to use Claude more inside my vault than for the code generation / review\u0026rdquo;.\nThe money trail confirms the story: on 2026-03-06, an Anthropic Pro subscription. Capacity exhausted within a week. On 2026-03-13, Max 5x; from May 2026, Max 20x.\nClaude became part of almost all of my workflows. I went from state \u0026ldquo;I am new to this\u0026rdquo; to Claude Certified Architect (Foundations) in nine months (June 2026).\nWhat settled it # To sum it up: Copilot was autocomplete; Cursor was an editor; Claude Code turned out to be a colleague - the difference is agency over files, tools and long tasks, not model quality alone.\nI took on multiple concurrent projects with the ambitious goal of organizing, deduplicating and finishing my digital archives and universe for the first time in 40 years (some of them are listed here).\nFunny fact: one of the projects is the migration of most of my data away from US-based cloud providers (AWS, Google, Apple) to local-first storage, backed up inside the EU. And the standing irony, recorded the day the migration project started: \u0026ldquo;The irony of me using the US based LLMs to solve this problem is not lost on me :-)\u0026rdquo;\nWhat \u0026ldquo;a virtual colleague\u0026rdquo; means in practice - agents, skills, a vault they co-manage - is the next post.\n","date":"September 22, 2026","externalUrl":null,"permalink":"/posts/2026-09-22-riding-the-llm-wave/","section":"Posts","summary":"This is a history of three years - from bookmarking ChatGPT articles to an AI-managed knowledge base; with a certification in the middle and one embarrassing self-assessment along the way.\nSpectator to User (2023) # I still remember my first interactions with ChatGPT (via the web, using the free version) sometime in early 2023. I wanted to have an episode guide of an excellent HBO series called Patria, a story of a Basque family during the ETA years. So I asked for it, and what ChatGPT produced was completely, utterly, unbelievably hallucinated: 12 episodes (the series has 8), a made-up story, randomly assigned actors, two thirds of them non-existent. One huge hallucination. I did not keep the transcript, but I remember it clearly. It was very disappointing, and my conclusion was: well, this is fun, but useless.\n","title":"Catching up: Riding the LLM Wave","type":"post"},{"content":"","date":"September 22, 2026","externalUrl":null,"permalink":"/tags/copilot/","section":"Tags","summary":"","title":"Copilot","type":"tags"},{"content":"","date":"September 22, 2026","externalUrl":null,"permalink":"/tags/llm/","section":"Tags","summary":"","title":"Llm","type":"tags"},{"content":"Both my wife and I have our favorite toys and leisure activities: mine are gadgets, books, internet and recently AI. And one of hers was always the garden. We also have many shared leisure activities like hiking and traveling, but that\u0026rsquo;s not the point; the point is how these two worlds, the world of AI and the world of gardening, suddenly connected.\nShe has been using AI, mainly Google Gemini, for some time, and was quite impressed with its results. I couldn\u0026rsquo;t really convince her that Claude (especially Opus and Fable) is in a different league. Technically, it wasn\u0026rsquo;t a fair comparison, because she was using the free models from Gemini and I was using the top models from Claude, but nevertheless.\nSo yesterday I installed the Claude Desktop application on her MacBook, and connected it to our Max-20 subscription. Afterwards I created two co-working projects: one of them for her new garden, and fed it the history of her previous Gemini conversations on the garden topic, plus a photo of a hand-drawn plan of the garden with the locations of existing and planned plants, some distances and some scribbled notes.\nWe were both amazed to see what Fable managed to do with it. It created a great-looking plan of the garden. It created a list of plants with recommendations, a separate markdown note for each, outlining which one needs to go to a more shady part and which to a more sunny one, and which has which water requirements (this was his own initiative, we just approved doing it). It drafted an irrigation system design so that the garden can survive our travels in summer. It made several more suggestions, which hadn\u0026rsquo;t even occurred to us. Well, there is no surprise they didn\u0026rsquo;t occur to me, as my capability for suggestions when it comes to the area of gardening is extremely limited; but my wife said that she actually saw several good suggestions from her point of view as an experienced gardener.\nWell done, Fable, well done!\n","date":"September 21, 2026","externalUrl":null,"permalink":"/notes/claude-the-garden-planner/","section":"Notes","summary":"Both my wife and I have our favorite toys and leisure activities: mine are gadgets, books, internet and recently AI. And one of hers was always the garden. We also have many shared leisure activities like hiking and traveling, but that’s not the point; the point is how these two worlds, the world of AI and the world of gardening, suddenly connected.\nShe has been using AI, mainly Google Gemini, for some time, and was quite impressed with its results. I couldn’t really convince her that Claude (especially Opus and Fable) is in a different league. Technically, it wasn’t a fair comparison, because she was using the free models from Gemini and I was using the top models from Claude, but nevertheless.\n","title":"","type":"notes"},{"content":"The pitch I once wrote for a conference talk still says it best: Obsidian has a cult following \u0026ldquo;not because it\u0026rsquo;s clever software, but because of what it isn\u0026rsquo;t: your notes are just plain markdown files in a folder on your computer. No database, no cloud lock-in, no proprietary format. Just files.\u0026rdquo;\nNothing ages as well as plain text; it has been the same since, well, files were invented. Markdown is just a very thin layer that gives the plain text some structure, and allows it to be rendered and displayed in an aesthetically pleasing way.\nFor me it wasn\u0026rsquo;t love at first sight; I actually tried Obsidian twice, and the first attempt didn\u0026rsquo;t work. The problem with Obsidian is that the plain application isn\u0026rsquo;t that appealing. The functionality, or at least most of the functionality I use today, lies in a combination of plugins. There are hundreds of them, and a proper setup can be quite intimidating. Also, unlike Logseq, which was the application that won the first round of the transition to plain text and markdown, the Obsidian core is not open source; most of the plugins are, but the application itself is not.\nWhat \u0026ldquo;just files\u0026rdquo; buys you # Future proof: every previous tool in the odyssey (except Logseq) died holding my notes hostage and forced a rescue or conversion project - markdown files in a folder cannot die that way Git as time machine: full history, diffs, sync - the vault is a repo. As long as you know what to do with the repo, you are covered. Locality: your files are your files. On your computer, not in the cloud in somebody else\u0026rsquo;s database. (as discovered in 2025) markdown is the native format for LLMs, and the cheapest one for them to consume and produce Lesson learned: the tooling is replaceable; the data is not. Obsidian is the current viewer of a corpus that would survive it and a convenient way to edit it quickly, but exactly the same thing can be done inside Visual Studio Code, inside Neovim or any other editor or environment. Hell, it\u0026rsquo;s just text.\nEcosystem blessing and curse # In the beginning I made the same mistake that many people do: I overdid it with plugins. I installed lots of them, which didn\u0026rsquo;t really help things a lot. Eventually I managed to find those that are actually useful for my workflow, by going over the installed list and weeding out the ones I never used or that contributed nothing. There are hundreds, if not thousands, of videos that tell you \u0026ldquo;this is absolutely a must-have set of plugins\u0026rdquo;. Some of them are even good. I watched a lot of them, but the catch is that you end up spending more time fine-tuning your note-taking system than actually working with your notes. Don\u0026rsquo;t go there. It\u0026rsquo;s a trap.\nHow it\u0026rsquo;s actually organized (three years in) # I ended up with an adapted version of the PARA system of Tiago Forte. If you don\u0026rsquo;t know it, read the book. PARA stands for projects, areas, resources, and archive, plus a daily-note journal - unbroken since April 2023. I made a few adaptations; for example, I am prefixing the main folders of PARA with a number so that they sort the way I want them to - therefore I have 1-proj, 2-area and so on. I also added an area that incubates possible future projects. I call it \u0026ldquo;forge\u0026rdquo;: creating a project is a commitment of sorts, and many ideas or thoughts never reach that stage. There is also an inbox area (0-inbox) where new notes land by default, and from where they are sorted and filed during a weekly review - something I borrowed from David Allen, \u0026ldquo;Getting Things Done\u0026rdquo;.\nI have my own standards of a frontmatter discipline: note types, tags taxonomy, a growth: field describing a permanent note lifecycle (stages acorn → seedling → evergreen → deadwood; 500+ notes were reclassified when this scale was introduced). Today this is maintained, enforced and checked by AI; my previous attempts to do that manually were not 100% successful, but that\u0026rsquo;s a different story.\nThe plugin shortlist that earns its keep: Templater, Dataview, Tasks, Quick Add (more on it in a dedicated post). I deliberately try hard to resist plugin sprawl; so far it is a draw ;-).\nThe biggest improvement comes from AI-based vault governance, where every piece of work is anchored to a project and a session protocol makes sure the progress gets tracked properly. But that\u0026rsquo;s, again, something for the next post.\nSecond-guessing, resolved # In 2025 I experienced an Obsidian commitment crisis after overdoing it with plugins and reaching a kind of messy state. I did a serious Logseq re-evaluation resulting in a long comparison note. The result: Obsidian stays, the plugins got trimmed and AI-based automation was added (hint: that was the time I switched to Anthropic). Lesson learned - re-choosing a tool on purpose beats never questioning it.\nWhere it\u0026rsquo;s going # The Obsidian vault is working area, workbench and thinking pad as well as storage.\nIt is the single source of truth that publishes outward: shared content to Notion, this very blog post from a vault folder through a staging pipeline - that story is two posts ahead.\nThe quiet unexpected payoff: when AI tooling arrived, a decade of notes in plain text turned out to be the perfect substrate. That\u0026rsquo;s the topic of the next post.\n","date":"September 20, 2026","externalUrl":null,"permalink":"/posts/2026-09-20-why-obsidian/","section":"Posts","summary":"The pitch I once wrote for a conference talk still says it best: Obsidian has a cult following “not because it’s clever software, but because of what it isn’t: your notes are just plain markdown files in a folder on your computer. No database, no cloud lock-in, no proprietary format. Just files.”\nNothing ages as well as plain text; it has been the same since, well, files were invented. Markdown is just a very thin layer that gives the plain text some structure, and allows it to be rendered and displayed in an aesthetically pleasing way.\n","title":"Catching up: Why Obsidian Won","type":"post"},{"content":"","date":"September 20, 2026","externalUrl":null,"permalink":"/categories/tools/","section":"Categories","summary":"","title":"Tools","type":"categories"},{"content":"Whatever I sit down to do with an AI coding assistant, the session ends the same way: the token budget is gone. It does not seem to matter what the task was. Fix one small bug, plan a migration, write a three-paragraph note like this one - by the end I am watching the context meter instead of the work.\nFor a while I read that as bad estimation on my part. I think it is something duller. The work is not what costs; the situating is. Before anything useful happens, the assistant has to be told where it is: which repo, which conventions, what was decided last week and why, which of my rules are real rules. That bill is roughly the same whether the edit that follows is one line or two hundred. So a trivial task and a serious one cost about the same to start, and only the serious one feels worth it afterwards.\nThe other half is mine. Given room, I keep going. A finished task is an invitation to look at the next thing while everything is still loaded, and that is exactly when the budget disappears - not on the work I planned, but on the three things I noticed along the way.\nI kinda hope this week will be different because I went to High Tatras for 3 days, did some hiking:\nbut there was internet in the hotel, so in the evening I was able to have a chat with Claude.\nSpeaking of hotel: Chata na Popradskom plese - greatly recommened\nParkinson\u0026rsquo;s law, with a meter attached.\n","date":"September 18, 2026","externalUrl":null,"permalink":"/notes/i-always-run-out-of-tokens/","section":"Notes","summary":"Whatever I sit down to do with an AI coding assistant, the session ends the same way: the token budget is gone. It does not seem to matter what the task was. Fix one small bug, plan a migration, write a three-paragraph note like this one - by the end I am watching the context meter instead of the work.\nFor a while I read that as bad estimation on my part. I think it is something duller. The work is not what costs; the situating is. Before anything useful happens, the assistant has to be told where it is: which repo, which conventions, what was decided last week and why, which of my rules are real rules. That bill is roughly the same whether the edit that follows is one line or two hundred. So a trivial task and a serious one cost about the same to start, and only the serious one feels worth it afterwards.\n","title":"","type":"notes"},{"content":"I have always taken notes. At first on paper - there are still many handwritten notebooks somewhere in the archives - but for the last thirty years or so most of them, if not all, have been digital. And digital always means an application and a format. I have tried a lot of them.\nWhile doing so I made pretty much every mistake one can make when it comes to choosing an application and settling on a workflow. What follows is a tour of the graveyard: a long line of tools, most of them now dead, and the lesson each one charged me on the way out.\nBefore the note apps # Before any of it, notes lived in whatever I happened to be writing documents with. In my Microsoft era that meant Word, and before that WordPerfect. Later I tried Google Docs for note-taking, and Apple Notes for the same job.\nThey failed me for much the same reasons every time. Search was poor. There was no linking between documents, and no meaningful way to embed one thing inside another. And there was no simple way to tell what had changed between two versions, though that one did genuinely improve in the later releases of Word. The end state was always the same: I was left holding binary blobs in a proprietary format, entirely dependent on a piece of software that somebody else was steering, usually in a direction I did not like.\nThe stations # Here are some of the note taking applications I tried and eventually abandoned.\nEvernote - the original digital brain, era now hard to even date. Used to be nice, and fast. Then it started to grow features, and eventually became slow, bloated, with complicated user interface, and utterly dependent on a fast internet connectivity. Quiver - the programmer\u0026rsquo;s notebook, and a good one for anything with code in it. What it could not do was live alongside anything else: hard to integrate with the other places my information already was, hard to tell how a note had changed over time, and synchronising it between machines was a problem that never really got solved. Curio (Mac) - visual boards, and genuinely good at them. The catch only shows up later: the work lives inside a bundle that nothing but Curio can open. Stop paying for it, or simply stop installing it, and the documents are still on disk and still out of reach. OneNote - I gave it an honest weekend, tutorials and all, and never came back to it. Part of what I was doing at the time was leaving the Microsoft ecosystem altogether, and OneNote was the one thing pulling me back towards Office 365 and the whole Microsoft online presence. Notion - home for my permanent notes for years, and it grew past ten thousand pages. It is really a collaboration tool rather than a pure note-taking one. The strange combination of tables and pages with pages embedded in them was very attractive at first, and the interface was lovely. Then the number of notes grew, search became slow, and it went the same way as Evernote: bloated, hard to track changes over time, hard to link, hard to embed. Unless you are part of a team working together inside Notion, a single note-taker gets more disadvantages out of it than advantages. Logseq - eleven months of real investment: templates, mobile, a publishing pipeline. The split I worked to back then was simple, permanent notes in Notion and fleeting notes in Logseq. I thought this was it. It appeared at the same time as Obsidian and looked like a purely open-source version of it. It was not. Technically it is an outliner, and not everything can be expressed as an outline. The learning curve was easier than Obsidian\u0026rsquo;s, which is why I picked it when I evaluated the two. A year or two later the Obsidian ecosystem had exploded and Logseq was stagnating. But I was on the right track, because Logseq was the first tool that solved the problems all the others had left me with. Never really adopted, for the record: - Roam (comparison articles only), - DEVONthink (evaluated as a document archive, not a note tool)\nThe wiki detour # Work notes went a different way. For years they lived in wikis, and the wiki always, sadly, ended up being Confluence from Atlassian.\nI even tried running my own. There was a time when Atlassian offered a free version for up to five users, for exactly this kind of experiment, so I took it, and then used it far less than I had hoped. The problem was the same one Notion has: the thing is built for collaboration first. Editing, at least in the early days of Confluence, was essentially a text box in a web page, which is nothing to get excited about. Capturing anything was full of friction, and the whole experience smelled too much like work for something meant to hold my own notes.\nThat created an interesting problem later on: keeping my local notes, which were markdown, in sync with the Confluence ones, which were in Atlassian\u0026rsquo;s own format, sitting in a database somewhere in their cloud. I did solve it, after a fashion, but never to my full satisfaction, and all in all it created about as many problems as it solved.\nI tried the same idea for my personal notes too, and experimented with MoinMoin and with TiddlyWiki. I liked MoinMoin\u0026rsquo;s text format. What I did not like was having to run a server for it, and the interface was, to put it politely, unpolished. There was friction everywhere in the workflow, and keeping it part of my daily routine was constant work. At the time I was living in two worlds, half on Mac and half on Windows, running a Python server on both and trying to keep them working and in sync with each other. That was simply too much trouble. Running a server on your own notebook was not ideal either, and mind you, this was before Node.js and Electron made exactly that the default way to ship an application.\nTiddlyWiki did not scale for me. I also had an uneasy feeling about entrusting everything I knew to a single monster file interwoven with JavaScript code, and diffing a TiddlyWiki file was no fun either.\nI liked the wiki model, and the linking between notes most of all, but that is a different story for a different post.\nThe switch, to the day # 2023-04-15: the last Logseq journal entry - and, the same day, the Obsidian vault repo is created. The two-brain split collapses into one tool overnight. Unbroken daily notes ever since August 2023, one late night: the migration-planning session - between 23:17 and 00:10, notes are created planning the transfer out of Evernote, Curio and Quiver. The graveyard gets an exhumation schedule. What the numbers say # Notes created per year: 365 (2023) → 165 (2024) → 1,271 (2025) → 2,639 (2026, through August). The 2025-26 explosion has a reason - that\u0026rsquo;s the AI post in this series. ~12,800 files in the vault today, plain markdown, in a git repo The lesson # Every one of those applications charged an exit tax on the way out, and the size of the tax was set by one thing, the format.\nTwo requirements came out of that, and they have not changed since.\nThe first is format longevity. Nothing beats plain text. It is not proprietary, and nothing comes close to it for diffing and tracking changes over time, which is what git was invented for. If notes are going to outlive the application they were written in, the format has to be future-proof, and future-proof means plain text, or markdown, which is plain text.\nThe second is control and locality. Notes have to be local first. Syncing between two machines is a secondary problem and can be solved on its own terms, but access to your own notes must never depend on connectivity.\nWhy Obsidian answered both is the next post in this series.\n","date":"September 17, 2026","externalUrl":null,"permalink":"/posts/2026-09-17-my-note-taking-odyssey/","section":"Posts","summary":"I have always taken notes. At first on paper - there are still many handwritten notebooks somewhere in the archives - but for the last thirty years or so most of them, if not all, have been digital. And digital always means an application and a format. I have tried a lot of them.\nWhile doing so I made pretty much every mistake one can make when it comes to choosing an application and settling on a workflow. What follows is a tour of the graveyard: a long line of tools, most of them now dead, and the lesson each one charged me on the way out.\n","title":"Catching up: My Note-Taking Odyssey","type":"post"},{"content":"","date":"September 17, 2026","externalUrl":null,"permalink":"/tags/note-taking/","section":"Tags","summary":"","title":"Note-Taking","type":"tags"},{"content":"","date":"September 3, 2026","externalUrl":null,"permalink":"/tags/aws/","section":"Tags","summary":"","title":"Aws","type":"tags"},{"content":"","date":"September 3, 2026","externalUrl":null,"permalink":"/tags/devops/","section":"Tags","summary":"","title":"Devops","type":"tags"},{"content":"","date":"September 3, 2026","externalUrl":null,"permalink":"/tags/dns/","section":"Tags","summary":"","title":"Dns","type":"tags"},{"content":"","date":"September 3, 2026","externalUrl":null,"permalink":"/tags/github-pages/","section":"Tags","summary":"","title":"Github-Pages","type":"tags"},{"content":"My company, Klassify s.r.o., has had a domain for a long time before it was even registered (I registered klassify.com way back in early 2000 in Canada, but never actually did anything with it) - and a web page since this afternoon. For all that time klassify.com carried only my email - there was no A record at all, nothing was served, and whoever looked up the company from an invoice or a contract got a browser error and, I suppose, some doubts about whether the company exists. So here is how it got fixed in one afternoon, in the order it happened and with the reasoning. Nothing here is clever or sophisticated or the only/the best way. The point is the sequence of creation: there are two places in it where it is quite easy to break something that matters more than a web page.\nI had two main reasons for doing this: one was that a company should have a web page. It was kinda weird when nothing showed up. The second reason was a non-trivial amount of catch emails in my Google Workspace for klassify.com, from some Indian company that apparently allocated a similar domain - klassify.io - and their customers kept using klassify.com to email them. These emails would arrive to me as a catch-up. At first I was trying to reply, then to autorespond, but it took too much time to review. This way, I kinda claimed the (virtual) lot.\nWhat I wanted (and what I did not) # One living company page - who Klassify is, what kind of engagements I take, certifications, links to the portfolio, the CV and this blog. Not a company website, nobody needs that. Plain hand-written index.html, no framework, no build step, no JavaScript, light and dark via prefers-color-scheme and that\u0026rsquo;s it.\nThe important constraint was the mail. Google Workspace is live on the domain, and the MX record is the one thing in that DNS zone that must survive whatever I do with the web part. The second constraint was cost - I wanted this to cost exactly nothing beyond the yearly domain renewal, which is what GitHub Pages on a public repository gives you.\nThe repository # See klassify-com/klassify.com on GitHub.\nFive files. The index.html itself, a CNAME file containing klassify.com (GitHub Pages reads this file and uses it as the custom domain), an empty .nojekyll (so that Pages serves the files as they are instead of running Jekyll over them), a README with the launch runbook so that future me knows what was done and why, and dns/route53-github-pages.json - the DNS change written as a Route 53 change batch.\nThat last one is a habit I recommend: commit the DNS change to the repo and it becomes something you can review, diff and repeat, instead of a memory of clicking around a console.\nStep 1 - create the repo and push # git add -A \u0026amp;\u0026amp; git commit -m \u0026#34;Klassify landing page\u0026#34; gh repo create klassify-com/klassify.com --public --source=. --remote=origin --push The gh command creates the repository under the organisation, adds the remote and pushes main, all in one go.\nStep 2 - turn on Pages, from the API # echo \u0026#39;{\u0026#34;build_type\u0026#34;:\u0026#34;legacy\u0026#34;,\u0026#34;source\u0026#34;:{\u0026#34;branch\u0026#34;:\u0026#34;main\u0026#34;,\u0026#34;path\u0026#34;:\u0026#34;/\u0026#34;}}\u0026#39; \\ | gh api -X POST repos/klassify-com/klassify.com/pages --input - \u0026ldquo;legacy\u0026rdquo; is what the web UI calls \u0026ldquo;Deploy from a branch\u0026rdquo;. For a single static file that is all one needs, no Actions workflow.\nTwo things I learned here. The response already came back with cname: klassify.com - the CNAME file in the repository root had set the custom domain by itself, so there was no separate \u0026ldquo;add domain\u0026rdquo; step at all. And you can prove the deployment works before creating a single DNS record: a repository called klassify.com is a project site, so it lives at klassify-com.github.io/klassify.com/, and that URL answered with a 301 to http://klassify.com/. The root klassify-com.github.io returns 404, which is correct and which confused me for a minute or two.\nStep 3 - DNS, the step that can break mail # This is what GitHub wants for an apex domain:\nName Type Value klassify.com A 185.199.108.153, 185.199.109.153, 185.199.110.153, 185.199.111.153 klassify.com AAAA 2606:50c0:8000::153, 2606:50c0:8001::153, 2606:50c0:8002::153, 2606:50c0:8003::153 www.klassify.com CNAME klassify-com.github.io The shape matters. A records on the apex, never a CNAME - a CNAME cannot coexist with any other record on the same name, so an apex CNAME would have quietly made the MX record unreachable and broken the mail. That is the whole reason why GitHub publishes fixed IP addresses for apex domains. The www name gets the CNAME, pointing at the organisation\u0026rsquo;s Pages hostname (not at the repository path) - GitHub routes it by the CNAME file, and it redirects to the apex.\nThe change batch uses CREATE, not UPSERT. If any of the three record sets had already existed, Route 53 would reject the whole batch instead of overwriting it - cheap insurance in a zone with live mail. It is a great idea to dig AAAA against a site that is already on GitHub Pages to assure it returned the same four addresses as the docs. Ten seconds, one class of typo eliminated. TTL is 300 seconds, so a rollback would propagate in minutes.\naws route53 change-resource-record-sets \\ --hosted-zone-id \u0026#34;$ZONE\u0026#34; \\ --change-batch file://dns/route53-github-pages.json Route 53 reported the change INSYNC in under a minute. Then the checks, in this order:\nMX still reads 1 smtp.google.com (good), http://klassify.com/ returns 200 with the right title, http://www.klassify.com/ redirects to the apex. HTTPS still failed at this point with GitHub\u0026rsquo;s own *.github.io wildcard certificate, which is expected - see the next step.\nStep 4 - the certificate that would not come # GitHub provisions a Let\u0026rsquo;s Encrypt certificate for a custom domain automatically once the DNS resolves, and the documentation says it can take up to an hour. Forty minutes in, the Pages settings page of the repository said \u0026ldquo;DNS check successful\u0026rdquo; right next to \u0026ldquo;Enforce HTTPS - unavailable because a certificate has not yet been issued\u0026rdquo;.\nRe-saving the same domain through the API changed nothing, there was no CAA record blocking Let\u0026rsquo;s Encrypt, and public resolvers all saw the right records. Everything was fine except the one thing I was waiting for.\nThe fix is in GitHub\u0026rsquo;s troubleshooting docs and it is blunt: remove the custom domain and add it back.\necho \u0026#39;{\u0026#34;cname\u0026#34;:null}\u0026#39; | gh api -X PUT repos/klassify-com/klassify.com/pages --input - echo \u0026#39;{\u0026#34;cname\u0026#34;:\u0026#34;klassify.com\u0026#34;}\u0026#39; | gh api -X PUT repos/klassify-com/klassify.com/pages --input - The certificate was approved within seconds of the second call, for klassify.com and www.klassify.com both, and https_enforced flipped to true on its own. The site was without its domain for about a second in between. Had I known, I would have done this after five minutes, not forty ;-)\nStep 5 - verify the domain for the organisation # A verified domain stops any other GitHub account from claiming klassify.com on Pages if this repository is ever deleted or renamed. Small thing, but the kind of small thing that is embarrassing when it happens.\nIt turns out there is no REST endpoint for this. I refreshed my token with the admin:org scope for nothing - the call returns 404 and the API docs for Pages and for Organisations simply do not list it. It is web UI only: Organisation settings, Pages, Verified domains, Add a domain.\nGitHub shows a TXT record to create (_github-pages-challenge-\u0026lt;org\u0026gt; under the domain, with a one-time value), so that was a second change batch of the same CREATE-only shape. One detail that bites: the TXT value inside the JSON has to carry its own literal quotes, as in \u0026ldquo;\u0026quot;value\u0026quot;\u0026rdquo;, otherwise the API rejects it. I waited until the record was visible from a public resolver, not only from the authoritative name server, and then clicked Verify. Verified on the first try.\nThe checklist for next time # dig +short A klassify.com; dig +short AAAA klassify.com dig +short CNAME www.klassify.com # klassify-com.github.io. dig +short MX klassify.com # 1 smtp.google.com. (must never change) curl -sI http://klassify.com/ | head -1 # 301 -\u0026gt; https curl -sI https://klassify.com/ | head -1 # 200 curl -sI https://www.klassify.com/ | head -1 # 301 -\u0026gt; https://klassify.com/ gh api repos/klassify-com/klassify.com/pages \\ --jq \u0026#39;{status,cname,https_enforced,cert:.https_certificate.state}\u0026#39; If I had to do it again tomorrow # Measure the zone before touching it - list every record and know where the mail is. Put the DNS change in a file in the repository, CREATE-only, and apply it from the CLI, the file is your audit trail. Prove the Pages deployment through the github.io project URL before the DNS exists. If the certificate has not shown up after a few minutes while the DNS check is green, remove and re-add the domain instead of waiting the hour. And verify the domain for the organisation in the browser, because the API cannot do it. The whole thing was a pair session with Claude Code - it measured the starting state, drafted the change batches and the runbook, drove the GitHub API calls and handed me the DNS commands to run myself. Which is exactly where I wanted a human hand on the keyboard.\n","date":"September 3, 2026","externalUrl":null,"permalink":"/posts/2026-09-03-how-klassify-com-went-live-on-github-pages/","section":"Posts","summary":"My company, Klassify s.r.o., has had a domain for a long time before it was even registered (I registered klassify.com way back in early 2000 in Canada, but never actually did anything with it) - and a web page since this afternoon. For all that time klassify.com carried only my email - there was no A record at all, nothing was served, and whoever looked up the company from an invoice or a contract got a browser error and, I suppose, some doubts about whether the company exists. So here is how it got fixed in one afternoon, in the order it happened and with the reasoning. Nothing here is clever or sophisticated or the only/the best way. The point is the sequence of creation: there are two places in it where it is quite easy to break something that matters more than a web page.\n","title":"How klassify.com went live: one static page, GitHub Pages and Route 53","type":"post"},{"content":"","date":"September 3, 2026","externalUrl":null,"permalink":"/tags/route53/","section":"Tags","summary":"","title":"Route53","type":"tags"},{"content":"My company, Klassify s.r.o., finally has a web page: klassify.com. Until now the domain carried only my email, and anyone who looked it up from an invoice or a contract found nothing at all.\nIt is a single static page, no framework: who Klassify is, what kind of engagements I take, the certifications, and where to find more. The \u0026ldquo;more\u0026rdquo; is this blog, so the landing page points here, and this note points back.\nWhat you will not find there is exaggeration, linked-in-ish AI crafted slop or bullshit about \u0026ldquo;thought leadership\u0026rdquo; and \u0026ldquo;service excellence\u0026rdquo; and so on. It\u0026rsquo;s a one-man corporation whose only reason to exist is to take care of the business side of my engagements.\nA longer post on how it was put together (GitHub Pages, Route 53, and a working session with Claude) is here: How klassify.com went live: one static page, GitHub Pages and Route 53.\n","date":"September 3, 2026","externalUrl":null,"permalink":"/notes/klassify-has-a-landing-page/","section":"Notes","summary":"My company, Klassify s.r.o., finally has a web page: klassify.com. Until now the domain carried only my email, and anyone who looked it up from an invoice or a contract found nothing at all.\nIt is a single static page, no framework: who Klassify is, what kind of engagements I take, the certifications, and where to find more. The “more” is this blog, so the landing page points here, and this note points back.\n","title":"","type":"notes"},{"content":"","date":"August 28, 2026","externalUrl":null,"permalink":"/tags/bratislava/","section":"Tags","summary":"","title":"Bratislava","type":"tags"},{"content":"We always had this dream back in Canada: retire to Europe, \u0026ldquo;ideally somewhere south\u0026rdquo;. This post is about how that plan half-worked, twenty years early, and how it landed us in Bratislava instead.\nHow Valencia actually happened (it was never a plan) # In 2012 we did our first ever trip to Spain (Madrid → Valencia → Barcelona), triggered by our daughter\u0026rsquo;s stay in Madrid. It was part of the student exchange where Silvia spent 3 months with a Spanish family in Madrid and we had a Spanish girl from that family with us in Ottawa. We loved the experience - it was different than Italy we knew, but intriguing. So we started to consider Spain as a possible retirement destination.\nThe trip from 2012 was followed by two more Spanish-course \u0026ldquo;edu-holidays\u0026rdquo; in Valencia; the city stuck: right size (vs Madrid/Barcelona), sea, food, climate, walkability, Turia city park. We stayed for 3 weeks, got a bit further with Spanish and had a great time.\nThen came 2015 when the company opened a Valencia office (a whole Hybris team inherited from a shutting-down firm relocated to Thinkwrap) and suddenly we had an EU office. The 6 hour time difference opened an interesting opportunity: the late-night 2-3 AM deployment of ecommerce systems would become more pleasant 8-9 morning jobs if performed from Spain. An opportunity and a good use case for a DevOps department inside the Valencia office. Unlike most of my colleagues, in addition to a Canadian passport I also had an EU passport which allowed me to live and work in Spain without the administrative barrier of a work permit.\nSo in April 2016 - we moved. After ~18 years in Canada we switched climate, ruling monarch, language and lifestyle and learned to navigate the Spanish bureaucracy. It was not always easy but very rewarding and definitely worth it. Living in a walkable city without owning a single car was a huge change. I have very fond memories of our lovely apartment at Joaquín Costa with terrazas, company office at Calle Colón, long walks in Turia, tostadas con tomate and jamón serrano, incomparable taste of fresh orange juice of Valencia oranges \u0026hellip;\nAlso at work - the years 2016–2019 were some of the best years of my professional life: I had a rare chance to experience the vibe, dynamic small-growing-company energy, second time around. As with many things in life - this time I was able to enjoy and experience it much deeper than the first time during the Thinknostic days.\nThe return nobody improvised # A good thing about Valencia is that it is only a 2.5 hour flight from Vienna, and thanks to low cost airlines (I remember tickets for 25-30 EUR) we could visit Bratislava and Slovakia much more often than from Canada. My wife started to teach at the university again and so we established a second base in Bratislava - bought an apartment to support that, while living in Valencia - most of the time she commuted, sometimes I worked one week a month from Bratislava. We had no plans to change that arrangement.\nWe even managed to convince our daughter to take a break from digital nomad life around Europe (she spent time in Germany, Italy, Spain) and to check out the \u0026ldquo;old country\u0026rdquo; (actually for her it was more like a new country - she was 2 when we left Slovakia) and establish a home base in Bratislava.\nAnd then in March 2020 Covid struck and luckily the shutdown caught all 3 of us in Bratislava. The travel stopped for several months, and the company went fully remote. The one thing pinning us to Valencia disappeared - it was absolutely the same to sit in the Bratislava apartment or the Valencia one and work remotely.\nSo my visit to Bratislava in March 2020, planned for 10 days, lasted 5 months and I found out that\nBratislava of 2020 was a very different city than the one I was leaving in 1998 it had many unique amenities one cannot find anywhere else (forest hiking trails starting in the city, coffee-bookshops culture, very agreeable climate) I actually loved it here So we decided to stay. An important factor was the proximity of the closest family: my parents are in their 80s. My brother and sister live in Slovakia and we could see each other much more often than from Spain. So Covid was the trigger and mechanism/enabler, not the only cause. If it had not come, our Spanish phase would probably have lasted much longer, possibly until now - but that is the \u0026ldquo;road not taken\u0026rdquo;. We gave up our Valencia flat and settled in Old Town, living about 200 m away from the place we lived before departing for Canada in 1998. Life makes strange loops ;-)\nThe next years were interesting from a logistic perspective. As I was living in Slovakia, I inevitably became a tax resident of Slovakia, while being employed (and paying taxes, deductions etc.) in Spain. From a legal point of view, I became a \u0026ldquo;trabajador desplazado\u0026rdquo; - a worker living abroad who is paid from Spain.\nIn theory, it is perfectly normal to live in one EU country and work in another. After all, this is what the EU labor mobility is about. And it works reasonably well as long as both parties are used to working together. Thousands of people from Slovakia work in the Czech Republic, Austria, Hungary, Germany and organizations on both ends work reasonably well together.\nThe situation is quite different when it comes to Slovakia and Spain (the famous \u0026ldquo;Spanish inquisition\u0026rdquo; sketch comes to mind for some strange reason, with tagline \u0026ldquo;nobody expects the Spanish bureaucracy\u0026rdquo;). The thing is that contacts and experience between Slovak social security and Seguridad Social offices are virtually non-existent. Regarding communication - on the Slovak side, nobody speaks Spanish, the only languages present are English/German/Hungarian. There are many bilingual people on the Spanish side, unfortunately they are bilingual in Spanish/Catalan, not English \u0026hellip; In the end, it took us several months to get the paperwork done and for each renewal several more months to re-establish the coverage.\nThe company I worked for evolved meanwhile - the Spanish office did not grow, cost cutting took away the awesome office at Colón and eventually even the second (much less amazing) office at Alfahuir. At the time of this writing, it still has an office in Valencia, but it is a coworking space (ironically, in a street in Eixample, 2 minutes away from where we used to live). The company\u0026rsquo;s focus seems to be India.\nSpanish employment ended in May 2024 and in the same month Klassify s.r.o. entered the Slovak register; my freelancing years began. The circle closes again, for the second time - I became a one-man company, same shape as the Ottawa contracting vehicle two decades earlier and very similar to what I used in Bratislava in the \u0026rsquo;90s, before emigration.\nWhy Bratislava, again - or wherever you go, there you are # I really enjoyed and liked the years we lived in Ottawa as well as in Valencia. Every city has something unique, available only there - cross-country skiing in Gatineau parc, Turia, Malé Karpaty. That is what you give up when you move. You also gain some. But there is only one country where you have cultural roots, whose history you truly experienced and understand. No amount of blending in or assimilation can replace this. Slovakia is where my parents, siblings, relatives, most of my old friends and half of my children live. One can make lots of great friends (and we did) but nobody can re-acquire childhood and school friends that share the world of your youth. As I said to one friend - emigration is something that one must live through to fully understand; it cannot be explained.\nLast but not least - only Bratislava has Martinus and Foxford café on Obchodná. Those who know me understand ;-).\nI still consider Canada one of my countries. I am a dual citizen, our son and daughter-in-law live there as well as many dear friends. There is still a box of documents on the other side of the ocean \u0026hellip; But for now, we are staying - unless Russia invades (again) or Slovakia turns into a second Belarus. Unlike before, there are a few options where to go.\nIt was Mečiar and his mafia government that made us leave in the \u0026rsquo;90s. Our current government is something I deeply disagree with, but there is a hope - if Hungary could get rid of Orbán, maybe Slovakia can eventually get a more reasonable government too.\nBut the southern dream is not dead. We plan to spend a semester as students at the University of Padua in 2027 to experience life in Italy for a few months and improve the language.\nAnd maybe one day I may find an irresistible project in Spain or Italy - who knows?\n","date":"August 28, 2026","externalUrl":null,"permalink":"/posts/2026-08-28-from-spain-to-bratislava-again/","section":"Posts","summary":"We always had this dream back in Canada: retire to Europe, “ideally somewhere south”. This post is about how that plan half-worked, twenty years early, and how it landed us in Bratislava instead.\nHow Valencia actually happened (it was never a plan) # In 2012 we did our first ever trip to Spain (Madrid → Valencia → Barcelona), triggered by our daughter’s stay in Madrid. It was part of the student exchange where Silvia spent 3 months with a Spanish family in Madrid and we had a Spanish girl from that family with us in Ottawa. We loved the experience - it was different than Italy we knew, but intriguing. So we started to consider Spain as a possible retirement destination.\n","title":"Catching up: From Spain to Bratislava (Again)","type":"post"},{"content":"","date":"August 28, 2026","externalUrl":null,"permalink":"/categories/life/","section":"Categories","summary":"","title":"Life","type":"categories"},{"content":"","date":"August 28, 2026","externalUrl":null,"permalink":"/tags/life/","section":"Tags","summary":"","title":"Life","type":"tags"},{"content":"","date":"August 28, 2026","externalUrl":null,"permalink":"/tags/spain/","section":"Tags","summary":"","title":"Spain","type":"tags"},{"content":"Most of my note-taking and thinking happens in Obsidian, so natural extension of this tool was to allow a pipeline that allows me to publish a thought or a quick note directly from Obsidian Vault into the this blog.\nEvery note starts its life as obsidian note, and through dedicated set of tags and custom attribute for publishing, it finds its way to the repository holding the source of this blog. Then another pipeline: the one that pre-compiles static website and publishes to GitHub takes over and makes the note visible.\nIt happened today, and this is a first quick note: being published through this mechanism. Thank you, Fable !\n","date":"August 23, 2026","externalUrl":null,"permalink":"/notes/obsidian-to-hugo-pipeline-is-alive/","section":"Notes","summary":"Most of my note-taking and thinking happens in Obsidian, so natural extension of this tool was to allow a pipeline that allows me to publish a thought or a quick note directly from Obsidian Vault into the this blog.\nEvery note starts its life as obsidian note, and through dedicated set of tags and custom attribute for publishing, it finds its way to the repository holding the source of this blog. Then another pipeline: the one that pre-compiles static website and publishes to GitHub takes over and makes the note visible.\n","title":"","type":"notes"},{"content":"","date":"August 22, 2026","externalUrl":null,"permalink":"/tags/blog/","section":"Tags","summary":"","title":"Blog","type":"tags"},{"content":"","date":"August 22, 2026","externalUrl":null,"permalink":"/tags/meta/","section":"Tags","summary":"","title":"Meta","type":"tags"},{"content":"The last post here is dated February 18, 2021. It was a perfectly ordinary how-to about Bitbucket permissions, and nothing about it suggested it would be the last one for five and a half years. There was no farewell post, no \u0026ldquo;taking a break\u0026rdquo; announcement. The blog just — stopped.\nThis post is the missing announcement, written from the other side.\nWhat happened # The short version: life kept running, and the writing habit didn\u0026rsquo;t.\nwe moved - again, we left Spain and now we\u0026rsquo;re living (again) in Bratislava, Slovakia my journey inside the company I cofounded (Thinknostic =\u0026gt; Thinkwrap) ended with its acquisition by Tenzing. I stayed a few more years in a DevOps / Platform role, left in 2024 I changed my priorities and my focus in many areas of life quite significantly I created a single-man consulting company - Klassify and started to pick interesting assignments, preferably short term / part time ones finally, after many years I started to dedicate a significant amount of my time to my hobbies and personal projects The side effect of the last two items is that I have now almost unrestricted freedom to write about things I am working on and playing with. No more locked-in Confluence posts, IP-barred solutions and self-imposed censorship :-)\nSome of these (maybe) deserve a more detailed post, which I (maybe) will get to in the catching-up series.\nThe world moved too # The gap happens to bracket the strangest shift of my professional life. When the last post went out in 2021, my toolkit was the classic DevOps/cloud stack, and \u0026ldquo;AI\u0026rdquo; mostly meant a category of conference talks. Writing this in 2026, a large language model helped resurrect the very site you are reading — the dormant Hugo build, the 550-post WordPress-era archive, the theme, the publishing pipeline. That story deserves its own post; the point here is that the person writing in 2026 works in a noticeably different world than the one who stopped in 2021.\nSince 2025, LLMs and especially Claude have become an integral part of my work, hobbies, life, and everyday activities. I remember that in 2016 or \u0026lsquo;17, when I did the previous upgrade and porting of this blog, it took 2 or 3 weeks until I got it working in Hugo. And fine-tuning for many more weeks as I discovered problems, issues, here and there. This time it took less than 2 hours, and my participation was mostly making decisions and confirming or providing additional details - Claude did all the heavy lifting. I resisted the temptation to \u0026ldquo;fix\u0026rdquo; my imperfect grammar, weird language constructs in the past entries, so everything from the past stays as it was written by a human without any AI involvement. I don\u0026rsquo;t plan to use Claude or any other LLMs to generate articles - there is too much AI slop out there anyway, and this is mostly interesting for me or for the very few people that know me.\nWhat I definitely want to do is to use Claude to review them and help me to make them sound a little bit better while still preserving my style.\nWhere I am now # The living version of \u0026ldquo;where am I now\u0026rdquo; has its own page: /now. That page gets updated; this post stays frozen as the marker between the two eras of this blog.\nWhat this blog becomes # Two things change with the restart:\nShort notes are now first-class. There is a new Notes stream for things that are worth writing down but not worth an essay — TILs, links, half-thoughts. The long-form posts continue when there is something long-form to say. The archive stays. All 555 posts back to 2006 remain exactly where they are, WordPress-era formatting warts and all. They are the record. The gap years may get backfilled with a few posts under the catching-up tag — what changed in the tools, in the work, in the reading — written when one of them wants to be written, not on a schedule.\nMostly this is for future me. But if someone else is reading: welcome back — I\u0026rsquo;m back too.\n","date":"August 22, 2026","externalUrl":null,"permalink":"/posts/2026-08-22-the-five-year-intermission/","section":"Posts","summary":"The last post here is dated February 18, 2021. It was a perfectly ordinary how-to about Bitbucket permissions, and nothing about it suggested it would be the last one for five and a half years. There was no farewell post, no “taking a break” announcement. The blog just — stopped.\nThis post is the missing announcement, written from the other side.\nWhat happened # The short version: life kept running, and the writing habit didn’t.\n","title":"The Five-Year Intermission","type":"post"},{"content":"This blog now has a notes stream — short things that don\u0026rsquo;t warrant a full post. It has its own RSS feed. This is the first one, mostly to prove the machinery works.\n","date":"August 22, 2026","externalUrl":null,"permalink":"/notes/notes-stream-exists/","section":"Notes","summary":"This blog now has a notes stream — short things that don’t warrant a full post. It has its own RSS feed. This is the first one, mostly to prove the machinery works.\n","title":"","type":"notes"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/tags/api/","section":"Tags","summary":"","title":"API","type":"tags"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/tags/bitbucket/","section":"Tags","summary":"","title":"Bitbucket","type":"tags"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/tags/git/","section":"Tags","summary":"","title":"Git","type":"tags"},{"content":" How to manage users and groups in Bitbucket # Use case:\nI want to maintain users and groups and their access to repositories in an organization in Bitbucket. To make sure I do not miss newly changed admin access, I want to use the Bitbucket API to retrieve the list of permissions on repository basis and on user/group bases.\nSetup # Bitbucket requires a username and password to access the API. This information is stored in environment variables BBUSER and BBPASSWORD. BBPASSWORD should be an access token / app password defined in the App passwords section of the user settings:\nThe variable BB represents the Bitbucket API URL\nexport BBUSER=\u0026lt;your-user-name\u0026gt; export BBPASSWORD=\u0026lt;your-user-token\u0026gt; export BB=\u0026#39;https://api.bitbucket.org/2.0\u0026#39; I am using a personal shortcut by creating the file ~/.ssh/bitbucket-token-work.secret with the contents described above and importing them, unless the variables are already defined:\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi Get list of users # ENTRIES=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/teams/${org}/members | jq .size) PAGELEN=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/teams/${org}/members | jq .pagelen) PAGES=$(expr $ENTRIES / $PAGELEN \u0026#34;+\u0026#34; 1) for i in $(seq 1 $PAGES) do curl -s --user $BBUSER:$BBPASSWORD ${BB}/teams/${org}/members\\?page\\=${i}\\\u0026amp;pagelen\\=${PAGELEN} | jq \u0026#34;.values[] | {nickname, account_id, \u0026#34;repos\u0026#34;: .links.repositories.href}\u0026#34; \u0026gt; ${org}-USERS-${i}.json done --- { \u0026#34;nickname\u0026#34;: \u0026#34;Dxxxx Sxxxx Oxxx\u0026#34;, \u0026#34;account_id\u0026#34;: \u0026#34;557058:e8xxxxxxdf\u0026#34;, \u0026#34;repos\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/repositories/%7B13xxxxxef4%7D\u0026#34; } { \u0026#34;nickname\u0026#34;: \u0026#34;Dxxx Axxx\u0026#34;, \u0026#34;account_id\u0026#34;: \u0026#34;55xxxxc0\u0026#34;, \u0026#34;repos\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/repositories/%7Ba76xxxxc9%7D\u0026#34; } ... Alternative format is to get all 3 fields on the same line:\ncurl -s --user $BBUSER:$BBPASSWORD https://api.bitbucket.org/2.0/workspaces/thinkwrap/permissions/repositories | jq \u0026#39;.values[] | .repository.name + \u0026#34;|\u0026#34; + .user.display_name + \u0026#34;|\u0026#34; + .permission\u0026#39; --- \u0026#34;smw-hybris|Rxxx Oxxx Rxxx|read\u0026#34; \u0026#34;smw-hybris|Source Bridge|admin\u0026#34; \u0026#34;smw-hybris|Jxxxx Fxxxx|admin\u0026#34; \u0026#34;smw-hybris|Yxxxx Lxxx|write\u0026#34; \u0026#34;smw-hybris|buildmastertw|read\u0026#34; .... Get list of users group # For accessing group we need to use the legacy 1.0 API. The API is down since 2019 but the group related endpoints are still supported, because Atlassian did not deliver the proper 2.0 of that endpoint implementation yet.\nThis is the output text format for every group in ${org}\n\u0026#34;BrownBagExamples|read|Yxxx Lxxx\u0026#34; \u0026#34;QA-Heroes||Dxxx Bxxx Mxxx\u0026#34; \u0026#34;sg-bitbucket-automation||sa-bitbucket\u0026#34; \u0026#34;Platform Engineers||Dxxxx Axxx;Mxxx Mxxx\u0026#34; \u0026#34;readonly|read|Source Bridge;Cxxxx Macxxxx;Read Only Source Access H3\u0026#34; \u0026#34;Developers|write|Jxxxx J. Cxxxx;Pxxxx Yxxxx;Dxxxx Dxxxx;Brendan Sxxx;Brant Mxxx;Dave Axxx;David Bxxx Mxxx;\u0026#34; .... There are three fields separated by \u0026lsquo;|\u0026rsquo; - group name, default access to new repositories (should be empty for non-admin and non-service accounts), and the list of member user names (separated by a \u0026lsquo;;\u0026rsquo;).\nHere is the code that produces that output:\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi for org in $(./bb-teams.sh ); do curl -s --user $BBUSER:$BBPASSWORD https://api.bitbucket.org/1.0/groups/${org}/ | jq \u0026#39;.[] | .name + \u0026#34;|\u0026#34; + .permission + \u0026#34;|\u0026#34; + ([.members[].display_name] | join(\u0026#34;;\u0026#34;)) \u0026#39; \\ | tee ${org}-group-access.txt done Getting matrix of access rights per repository and user # User groups are the preferred way of managing permissions. At the repository level, the effective rights is a combination of the access assigned through user groups and the access rights assigned directly to users - see the example\nWe will produce a matrix of the information in 2 steps: at first, we will generate a linear list of triplets in the form REPO-NAME|USER-NAME|access\n\u0026#34;smw-hybris|Rxxx Oxxx Rxxx|read\u0026#34; \u0026#34;smw-hybris|Source Bridge|admin\u0026#34; \u0026#34;smw-hybris|Jxxxx Fxxxx|admin\u0026#34;\u0026#34; The API call that generates this list is\ncurl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/workspaces/${org}/permissions/repositories?pagelen=${PAGELEN}\u0026amp;page=${i}\u0026#34; | jq \u0026#39;.values[] | .repository.name + \u0026#34;|\u0026#34; + .user.display_name + \u0026#34;|\u0026#34; + .permission\u0026#39; | tee ${org}-repo-users-${i}.txt The script running the call for every repository in the workspace is bb-repo-user.sh\nIt expects single argument - a workspace name (e.g. pivotree_h3) and generates file named WORKSPACE-repo.permissions (e.g. pivotree_h3-repo.permissions) with the structure above - sorted.\nIt can run long time a generates large number of temporary files.\nIt also generates output during run to see how far it proceeded.\n./bb-repo-user.sh pivotree_h3 Logged on as user { \u0026#34;account_id\u0026#34;: \u0026#34;55xxxxxxda\u0026#34;, \u0026#34;uuid\u0026#34;: \u0026#34;{d8xxxxxx08}\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;miro-adamy-PVT\u0026#34;, \u0026#34;display_name\u0026#34;: \u0026#34;Miro Adamy\u0026#34;, \u0026#34;snippets\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/snippets/%7Bd8dxxxxxxx08%7D\u0026#34;, \u0026#34;self\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/users/%7Bd8xxxxxxxxx08%7D\u0026#34; } ENTRIES=2556, PAGELEN=100, PAGES=26 1 ... curl -s --user ...:... https://api.bitbucket.org/2.0/workspaces/pivotree_h3/permissions/repositories?pagelen=100\u0026amp;page=1 \u0026#34;dive-data-manager|Source Bridge|read\u0026#34; \u0026#34;dive-data-manager|Pxxxxx Lxxxxg|admin\u0026#34; \u0026#34;dive-data-manager|Dxxxx Dxxxx|admin\u0026#34; ... 2 ... curl -s --user ...:... https://api.bitbucket.org/2.0/workspaces/pivotree_h3/permissions/repositories?pagelen=100\u0026amp;page=2 \u0026#34;pvt-sgm-size-norm-prog|Source Bridge|read\u0026#34; \u0026#34;pvt-sgm-size-norm-prog|Yxxxxx Lxxxxx|read\u0026#34; ... The second step is to generate JSON files proving different views of this data. The pythin script expects as input one or more files in the format of WORKSPACE-repo.permissions\npython3 generate_repo_stats.py pivotree_h3-repo.permissions Processed 2556 lines The script creates 4 files:\nREPO_BY_ACCESS.json # { \u0026#34;ApiGateway\u0026#34;: { \u0026#34;admin\u0026#34;: [ \u0026#34;Bxxxx Mxxxxx\u0026#34;, \u0026#34;Bxxxx Sxxxxx\u0026#34;, ], \u0026#34;read\u0026#34;: [ \u0026#34;User Name2\u0026#34;, \u0026#34;User Name3\u0026#34;, ], \u0026#34;write\u0026#34;: [ \u0026#34;User Name4\u0026#34;, \u0026#34;User Name5\u0026#34;, ] }, \u0026#34;JIRA-voting\u0026#34;: { \u0026#34;admin\u0026#34;: [ \u0026#34;User Name6\u0026#34;, \u0026#34;User Name7\u0026#34;, ], \u0026#34;read\u0026#34;: [ \u0026#34;User Name8\u0026#34;, \u0026#34;User Name9\u0026#34;, ], \u0026#34;write\u0026#34;: [ \u0026#34;User Name1\u0026#34;, \u0026#34;User Name2\u0026#34;, ] } } REPO_BY_USER.json # { \u0026#34;ApiGateway\u0026#34;: { \u0026#34;User Name1\u0026#34;: \u0026#34;admin\u0026#34;, \u0026#34;User Name2\u0026#34;: \u0026#34;read\u0026#34;, \u0026#34;Read Only Source Access H3\u0026#34;: \u0026#34;read\u0026#34;, \u0026#34;Source Bridge\u0026#34;: \u0026#34;read\u0026#34;, \u0026#34;User Name3\u0026#34;: \u0026#34;write\u0026#34; }, \u0026#34;JIRA-voting\u0026#34;: { \u0026#34;User Name1\u0026#34;: \u0026#34;admin\u0026#34;, \u0026#34;User Name3\u0026#34;: \u0026#34;admin\u0026#34;, \u0026#34;Read Only Source Access H3\u0026#34;: \u0026#34;read\u0026#34;, \u0026#34;Source Bridge\u0026#34;: \u0026#34;read\u0026#34;, \u0026#34;User Name5\u0026#34;: \u0026#34;read\u0026#34; } } USER_BY_ACCESS.json # { \u0026#34;User Name1\u0026#34;: { \u0026#34;admin\u0026#34;: [ \u0026#34;repo-1\u0026#34;, \u0026#34;repo-2\u0026#34; ], \u0026#34;write\u0026#34;: [ \u0026#34;dive-testing-service\u0026#34; ] }, \u0026#34;User Name2\u0026#34;: { \u0026#34;read\u0026#34;: [ \u0026#34;pvt-sls-starter\u0026#34; ] } } USER_BY_REPO.json # { \u0026#34;User Name1\u0026#34;: { \u0026#34;repo-1\u0026#34;: \u0026#34;admin\u0026#34;, \u0026#34;repo-2\u0026#34;: \u0026#34;read\u0026#34; }, \u0026#34;User Name2\u0026#34;: { \u0026#34;pvt-sls-starter\u0026#34;: \u0026#34;read\u0026#34; } } } These can be easily processed using JQ to retrieve any type of information, and together with permission file it can be used to quickly find out answers to administration related questions\nExamples # What repos does Juan have admin ccess to ?\ncat *.permissions | grep admin | grep \u0026#39;Juan\u0026#39; | sed \u0026#39;s/\u0026#34;//g\u0026#39; | cut -d\u0026#39;|\u0026#39; -f1 dive-cx-account dive-cx-js-sdk dive-cx-ui .... Who can access repo ApiGateway\ncat *.permissions | sed \u0026#39;s/\u0026#34;//g\u0026#39; | grep ApiGateway | cut -d\u0026#39;|\u0026#39; -f2,3 User Name1|admin User Name2|read Miro Adamy|admin Read Only Source Access H3|read Source Bridge|read .... NOTE\nThis was also published on our cloud team blog\n","date":"February 18, 2021","externalUrl":null,"permalink":"/posts/2021-02-18-bitbucket-user-groups/","section":"Posts","summary":"How to manage users and groups in Bitbucket # Use case:\nI want to maintain users and groups and their access to repositories in an organization in Bitbucket. To make sure I do not miss newly changed admin access, I want to use the Bitbucket API to retrieve the list of permissions on repository basis and on user/group bases.\n","title":"How to monitor Bitbucket user and group permissions with API","type":"post"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/categories/howto/","section":"Categories","summary":"","title":"Howto","type":"categories"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/tags/python/","section":"Tags","summary":"","title":"Python","type":"tags"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/tags/shell/","section":"Tags","summary":"","title":"Shell","type":"tags"},{"content":"","date":"February 18, 2021","externalUrl":null,"permalink":"/categories/version-control/","section":"Categories","summary":"","title":"Version Control","type":"categories"},{"content":"","date":"February 17, 2021","externalUrl":null,"permalink":"/tags/github/","section":"Tags","summary":"","title":"Github","type":"tags"},{"content":" Mirroring large number of GitHub or Bitbucket repositories # Use case:\nI want to create local clone of a large number of repositories from an organization in GitHub / Bitbucket.\nAssumptions # user has SSH key registered with the GH / BB - can clone using ssh protocol user has successfully cloned at least one repo from command line before (the /etc/hosts contains host entries for BB and GH) user has modern version of Python 3 installed (3.6 or better) user has local installation of a reasonably modern Git Steps # First I use the ./bb-repo-links.sh and ./gh-repo-links.sh to generate list of repositories. See these blog articles: How to list repositories in Bitbucket and How to list repositories in github\nThese are text files and have the structure like this:\nEXFO|git@bitbucket.org:thinkwrap/exfo-tw-docker-jenkins.git FARO|git@bitbucket.org:thinkwrap/faro-infrastructure.git H3|git@bitbucket.org:thinkwrap/headless-api-gateway.git H3|git@bitbucket.org:thinkwrap/headless-cart-service.git H3|git@bitbucket.org:thinkwrap/headless-catalog-service.git H3|git@bitbucket.org:thinkwrap/headless-connector-atg.git H3|git@bitbucket.org:thinkwrap/headless-connector-contentful.git The first field is the project prefix, and the second is the SSH url for cloning the repository. They are separated by the | character.\nCloning is trivial:\npython3 ./process_repos.py NAME-OF-THE-CONTROL-FILE .... e.g.\npython3 ./process_repos.py pivotree_h3.bb-repo2 pvtrlabs.gh-repo The Python script uses ../MIRROR as the starting point for the mirrored tree.\nThis can be changed by exporting the variable MIRROR_ROOT\nexport MIRROR_ROOT = \u0026#39;../MIRROR2\u0026#39; The generated structure looks like this:\nPLAFORM \u0026gt; ACCOUNT \u0026gt; PROJECT \u0026gt; REPO\nwhere:\nPLATFORM is bitbucket.org or github.com Account is organization name within the platform PROJECT is project name for Bitbucket, defaults to \u0026lsquo;src\u0026rsquo; for GitHub REPO is the repository name NOTE: the names of some projects are \u0026lt; edited \u0026gt;.\n. ├── bitbucket.org │ ├── pivotree_h3 │ │ ├── BrownBagExamples │ │ │ └── apigateway │ │ ├── DATA │ │ │ └── sample-data-aws │ │ ├── DIVE │ │ │ ├── customer-mgmt-api │ │ │ ├── data-science-practice ... │ │ │ ├── pvt-admin-mgmt-api │ │ │ └── sagemaker-microservices │ │ ├── DIVE20 │ │ │ ├── dive-data-manager ... │ │ │ └── tr-sgm-duplicates-svc │ │ ├── DIVECX │ │ │ ├── dive-cx-account │ │ │ ├── dive-cx-account-fork ... │ │ │ └── pvt-ssm-manager │ │ └── starter │ │ ├── pvt-node-module-starter │ │ ├── pvt-node-starter │ │ ├── pvt-pipeline-example │ │ └── pvt-sls-starter │ └── thinkwrap │ ├── \u0026lt;PRJ\u0026gt;-CLOUD │ │ └── \u0026lt;prj\u0026gt;-cloud │ ├── Admin │ │ └── tw-bitbucket-admin │ ├── \u0026lt;PROJECT_1\u0026gt; │ │ ├── \u0026lt;prj1\u0026gt;-infra │ │ └── \u0026lt;prj1\u0026gt;-robot │ ├── BOPIS │ │ ├── bopis_automation_platform │ │ └── pvt-bopis │ ├── \u0026lt;PRJ2\u0026gt; │ │ └── \u0026lt;prj2\u0026gt;-vtex-poc │ ├── \u0026lt;PRJ3\u0026gt; ... │ │ └── \u0026lt;prj4\u0026gt;-testautomation │ ├── ZZZ-Archived-Repos │ │ └── oneclick-starter │ └── microbase │ ├── micro-alexa-search │ ├── micro-alexa-search-skill │ ├── micro-backoffice │ ├── micro-cart-service │ ├── micro-catalog-service │ ├── micro-customer-service │ ├── micro-docker-nginx │ ├── micro-docker-service │ ├── micro-oauth-service │ ├── micro-payment-service │ ├── micro-promotion-service │ ├── micro-recommendation-service │ ├── micro-stock-service │ ├── micro-tax-service │ ├── microbase │ └── www.microbase.io └── github.com ├── pivotree-tech-blog │ └── src │ ├── hugo101 │ ├── pivotree-tech-blog-source-poc │ ├── pivotree-tech-blog.github.io │ └── story ├── pvtrlabs │ └── src │ ├── action-skip-ci │ ├── at-aws-onelogin-multiapp │ ├── at-cloudhealth │ ├── at-opsgenie-integrations .... │ ├── terraform-tfe-workspace │ ├── terraform-tfe-workspace-full │ ├── test-limited-tfc-access │ └── test-repo └── thinkwrap └── src ├── ML-Live-Beginner ├── ML-Live-Intermediate ├── Tiny-Python-3.6-Notebook ├── aaac-starter-template ├── aws-cost-and-usage-report ├── aws-ml-guide ├── blast-radius ├── docker-aws-cli ├── docker-kubernetes-cli ├── docker-kubernetes-cli-helm ├── docker-node-base-pipelines ├── docker-node-sls-pipelines ├── docker-node-sls-pipelines-aws ├── docker-python-base-pipelines ├── docker-sls-cli ├── docker-terraform-cli ├── docker-terraform-cli-helm ├── ecs-deep-dive-2018 ├── kubernetes-in-action ├── programming-with-data ├── sgviz ├── ssm-parameter-store ├── terraform-ecs-fargate └── universal-recommender 549 directories, 0 files Updating # If the Python script encounters an existing repository, it tries to do an update by fetching the remote updates. It does NOT merge.\nNOTE\nThis was also published on our cloud team blog\n","date":"February 17, 2021","externalUrl":null,"permalink":"/posts/2021-02-17-mirroring-repos/","section":"Posts","summary":"Mirroring large number of GitHub or Bitbucket repositories # Use case:\nI want to create local clone of a large number of repositories from an organization in GitHub / Bitbucket.\nAssumptions # user has SSH key registered with the GH / BB - can clone using ssh protocol user has successfully cloned at least one repo from command line before (the /etc/hosts contains host entries for BB and GH) user has modern version of Python 3 installed (3.6 or better) user has local installation of a reasonably modern Git Steps # First I use the ./bb-repo-links.sh and ./gh-repo-links.sh to generate list of repositories. See these blog articles: How to list repositories in Bitbucket and How to list repositories in github\n","title":"How to mirror Github and Bitbucket repositories","type":"post"},{"content":" How to list repositories in GitHub # Use Case:\nI want to maintain repositories in an organization in GitHub. To make sure I do not miss newly added ones, I want to use API access to retrieve the list of repositories in the organization.\nSetup # GitHub requires a token to access the API. This token is stored in an environment variable github_token and can be generated in the user profile section - settings - developer settings.\nThe variable gh represents the GitHub API URL.\nexport gh=https://api.github.com export github_token=\u0026lt;your-secret-token\u0026gt; I am using a personal shortcut by creating the file ~/.ssh/github-token.secret with the content described above and importing them, unless the variables are already defined:\nif [ -z \u0026#34;$github_token\u0026#34; ] ; then echo importing the token from ~/.ssh/github-token.secret . ~/.ssh/github-token.secret) fi if [ -z \u0026#34;$github_token\u0026#34; ] ; then echo \u0026#34;you must export variable github_token \u0026#34; exit 2 fi Retrieving the list of organizations # With the configuration done above, you can run this command:\ncurl -s -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \u0026#34;${gh}/user/orgs\u0026#34; \\ | jq \u0026#39;.[].login\u0026#39; | sed \u0026#39;s/\u0026#34;//g\u0026#39; --- thinkwrap pvtrlabs pivotree-tech-blog The output is list of all organizations for the currently authenticated user.\nthe full script - ./gh-teams.sh\nif [ -z \u0026#34;$github_token\u0026#34; ] ; then echo using token github_token from ~/.ssh/github-token.secret . ~/.ssh/github-token.secret fi if [ -z \u0026#34;$ghteams\u0026#34; ] ; then #echo my teams curl -s -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \u0026#34;${gh}/user/orgs\u0026#34; \\ | jq \u0026#39;.[].login\u0026#39; | sed \u0026#39;s/\u0026#34;//g\u0026#39; else echo \u0026#34;$ghteams\u0026#34; fi The output is list of all teams for the currently authenticated user.\nexample:\n./gh-teams.sh thinkwrap pvtrlabs pivotree-tech-blog Retrieving the list of repositories for an organization # With the configuration done above, you can run this command:\ncurl -s -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \\ \u0026#34;${gh}/orgs/${username}/repos?per_page=${pagelen}\u0026amp;page=${i} where username is the name of the organization or user that owns the repositories.\nFor this call we need to use paging because the default count of results GitHub returns is 30. We can retrieve the counts of repositories from the organization metadata.\nWe need to loop for every page and store the JSON retrieved in temporary files. These JSON files are then processed and generate the .gh-repos file in the same format as the BitBucket case:\nprojectname|git_url\nsrc|git@github.com:pivotree-tech-blog/hugo101.git src|git@github.com:pivotree-tech-blog/pivotree-tech-blog-source-poc.git src|git@github.com:pivotree-tech-blog/pivotree-tech-blog.github.io.git src|git@github.com:pivotree-tech-blog/story.git The script expects 1 argument - the name of the organization or user:\n#!/bin/bash set -e progname=$(basename $0) die() { echo \u0026#34;$progname: $*\u0026#34; \u0026gt;\u0026amp;2 exit 1 } usage() { if [ \u0026#34;$*\u0026#34; != \u0026#34;\u0026#34; ] ; then echo \u0026#34;error: $*\u0026#34; fi cat \u0026lt;\u0026lt; eof usage: $progname [option ...] gh-team-or-user-name generate the list of the repositiories for given team or used options: -h, --help display this usage message and exit -d, --debug set debug = true eof exit 1 } debug=0 username=\u0026#34;undefined\u0026#34; if [ $# -eq 0 ] ; then echo missing argument: github team usage fi while [ $# -gt 0 ] ; do case \u0026#34;$1\u0026#34; in -h|--help) usage ;; -d|--debug) debug=1 ;; -*) usage \u0026#34;unknown option \u0026#39;$1\u0026#39;\u0026#34; ;; *) if [ \u0026#34;$username\u0026#34; = \u0026#34;undefined\u0026#34; ] ; then username=\u0026#34;$1\u0026#34; else usage \u0026#34;too many arguments\u0026#34; fi ;; esac shift done if [ -z \u0026#34;$github_token\u0026#34; ] ; then echo importing the token from ~/.ssh/github-token.secret . ~/.ssh/github-token.secret) fi if [ -z \u0026#34;$github_token\u0026#34; ] ; then echo \u0026#34;you must export variable github_token \u0026#34; exit 2 fi # display info about the user echo logged on as user curl -s -h -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \u0026#34;${gh}/user\u0026#34; \\ | jq \u0026#39;{login, id, html_url, name, public_repos, total_private_repos}\u0026#39; curl -s -h -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \u0026#34;${gh}/orgs/${username}\u0026#34; \\ \u0026gt; ${username}-ghteam-info.json echo team info - see ${username}-ghteam-info.json # produce list of the repositories in format slug=repo # echo curl -s -u $creds \u0026#34;${bb}/${team}?pagelen=${pagelen}\u0026#34; entries=$(curl -s -h -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \u0026#34;${gh}/orgs/${username}\u0026#34; | jq \u0026#39;[.total_private_repos, .public_repos] | add\u0026#39;) pagelen=100 pages=$(expr $entries / $pagelen \u0026#34;+\u0026#34; 1) echo the team $username has $entries repos in $pages pages for i in $(seq 1 $pages) do curl -s -h \u0026#34;accept: application/vnd.github.v3+json\u0026#34; -h \u0026#34;authorization: token ${github_token}\u0026#34; \\ \u0026#34;${gh}/orgs/${username}/repos?per_page=${pagelen}\u0026amp;page=${i}\u0026#34; \u0026gt; ${username}-repo-${i}.json done for i in $(seq 1 $pages) do jq \u0026#39;.[].ssh_url\u0026#39; \u0026lt; ${username}-repo-${i}.json | sed \u0026#39;s/\u0026#34;//g\u0026#39; | awk \u0026#39;{print \u0026#34;src|\u0026#34; $1 }\u0026#39; \u0026gt; ${username}-${i}.repos done rm -f ${username}-repo-*.json # make sure the file is empty/none - we will append rm -f ${username}.gh-repos cat ${username}-*.repos | sort \u0026gt;\u0026gt;${username}.gh-repos rm ${username}-*.repos echo see ${username}.gh-repos NOTE\nThis was also published on our cloud team blog\n","date":"February 16, 2021","externalUrl":null,"permalink":"/posts/2021-02-16-github-list-repos/","section":"Posts","summary":"How to list repositories in GitHub # Use Case:\nI want to maintain repositories in an organization in GitHub. To make sure I do not miss newly added ones, I want to use API access to retrieve the list of repositories in the organization.\nSetup # GitHub requires a token to access the API. This token is stored in an environment variable github_token and can be generated in the user profile section - settings - developer settings.\n","title":"How to list Github repositories and users","type":"post"},{"content":" How to list repositories in Bitbucket # Use case:\nI want to maintain repositories in an organization in Bitbucket. To make sure I do not miss newly added ones, I want to use API access to retrieve the list of all repositories in the organization.\nSetup # Bitbucket requires a username and password to access the API. This information is stored in the environment variables BBUSER and BBPASSWORD. The BBPASSWORD should be an access token / app password defined in the App passwords section of the user settings:\nThe variable BB contains the Bitbucket API URL\nexport BBUSER=\u0026lt;your-user-name\u0026gt; export BBPASSWORD=\u0026lt;your-user-token\u0026gt; export BB=\u0026#39;https://api.bitbucket.org/2.0\u0026#39; I am using a personal shortcut by creating the file ~/.ssh/bitbucket-token-work.secret with the contents described above and importing them, unless the variables are already defined:\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi Getting list of organizations # With the configuration done above, you can run this command:\ncurl -s -u \u0026#34;$BBUSER:$BBPASSWORD\u0026#34; \u0026#34;${BB}/teams?role=member\u0026#34; | jq \u0026#39;.values[].username\u0026#39; | sed \u0026#39;s/\u0026#34;//g\u0026#39; --- thinkwrap tenzingcom pivotree_h3 The output is a list of all organizations for the currently authenticated user.\nThe full script - ./bb-teams.sh\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi if [ -z \u0026#34;$BBTEAMS\u0026#34; ] ; then curl -s -u \u0026#34;$BBUSER:$BBPASSWORD\u0026#34; \u0026#34;${BB}/teams?role=member\u0026#34; \\ | jq \u0026#39;.values[].username\u0026#39; | sed \u0026#39;s/\u0026#34;//g\u0026#39; else echo \u0026#34;$BBTEAMS\u0026#34; fi The output is a list of all team for the currently authenticataed user.\nExample:\n✗ ./bb-teams.sh thinkwrap tenzingcom pivotree_h3 Getting list of users for an organization # With the configuration done above, you can run this command:\ncurl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members\u0026#34; | jq \u0026#39;.values[].display_name\u0026#39; --- \u0026#34;Axxxxx Chxxxx\u0026#34; \u0026#34;Dxx Axx Oxxx\u0026#34; \u0026#34;Axxxx Kxx\u0026#34; \u0026#34;Axxxx Ixxxx Esxxxx\u0026#34; \u0026#34;Axxx Rxxx Exxxx\u0026#34; ... The number of users can be large so we need to handle paging, using request parameters (the $org variable is name of the team):\nENTRIES=$(curl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?limit=100\u0026#34; | jq .size) PAGELEN=$(curl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?limit=100\u0026#34; | jq .pagelen) PAGES=$(expr $ENTRIES / $PAGELEN \u0026#34;+\u0026#34; 1) --- echo $org $ENTRIES $PAGELEN $PAGES thinkwrap 120 50 3 The JSON returned by /teams/$org/members contains 3 entries - pagelen, size and an array of records:\ncurl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?limit=100\u0026#34; | jq . | head { \u0026#34;pagelen\u0026#34;: 50, \u0026#34;size\u0026#34;: 120, \u0026#34;values\u0026#34;: [ { \u0026#34;display_name\u0026#34;: \u0026#34;Axxx Chxxxx\u0026#34;, \u0026#34;has_2fa_enabled\u0026#34;: null, \u0026#34;links\u0026#34;: { \u0026#34;hooks\u0026#34;: { \u0026#34;href\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/users/%7Bd6383ed0-xxxxxx-bb56d6a%7D/hooks\u0026#34; We will run the requests inside a loop to store each result in a temporary file, and then concatenate them:\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi for org in $(./bb-teams.sh ); do ENTRIES=$(curl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?limit=100\u0026#34; | jq .size) PAGELEN=$(curl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?limit=100\u0026#34; | jq .pagelen) PAGES=$(expr $ENTRIES / $PAGELEN \u0026#34;+\u0026#34; 1) rm $org-members-*.json for i in $(seq 1 $PAGES) do curl -s --user $BBUSER:$BBPASSWORD \u0026#34;${BB}/teams/${org}/members?pagelen=${PAGELEN}\u0026amp;page=${i}\u0026#34; | jq \u0026#39;.values[].display_name\u0026#39; | tee $org-members-${i}.json done rm ${org}.users cat $org-members-*.json \u0026gt;\u0026gt; ${org}.users rm $org-members-*.json done This script creates multiple output files ${org}.users - e.g. thinkwrap.users containing the users in each group.\nRetrieving repositories for an organization # With the configuration done above, you can run this command:\ncurl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username} where username is name of the organization or name of the user that owns the repositories.\nAs with users, the JSON response contains 3 keys: size, pagelen and an array of values. These need to be retrieved first and used in consequent calls:\n# Produce list of the repositories in format slug=REPO # echo curl -s -u $CREDS \u0026#34;${BB}/${TEAM}?pagelen=${PAGELEN}\u0026#34; ENTRIES=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username} | jq .size) PAGELEN=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username} | jq .pagelen) PAGES=$(expr $ENTRIES / $PAGELEN \u0026#34;+\u0026#34; 1) echo The TEAM $username has $ENTRIES repos for i in $(seq 1 $PAGES) do curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username}\\?page\\=${i}\\\u0026amp;pagelen\\=${PAGELEN} \u0026gt; ${username}-REPO-${i}.json done for i in $(seq 1 $PAGES) do jq \u0026#39;.values[].links.clone[].href\u0026#39; \u0026lt; ${username}-REPO-${i}.json | grep -v https | sed \u0026#39;s/\u0026#34;//g\u0026#39; \u0026gt; ${username}-${i}.repos done # Make sure the file is empty/none - we will append rm -f ${username}.bb-repos cat ${username}-*.repos | sort \u0026gt;\u0026gt;${username}.bb-repos rm ${username}-*.repos echo See ${username}.bb-repos The script first produces one temporary file per page containing repository information named ${username}-REPO-${i}.json. From these files, the second loop extracts only clone links .values[].links.clone[].href for SSH access and stores them in a second temporary file named ${username}-${i}.repos. These are then concatenated and sorted, and one file per organization (or user) is generated named ${org}.bb-repos.\nThe script expects 1 argument - the name of the organization or user:\n#!/bin/bash set -e PROGNAME=$(basename $0) die() { echo \u0026#34;$PROGNAME: $*\u0026#34; \u0026gt;\u0026amp;2 exit 1 } usage() { if [ \u0026#34;$*\u0026#34; != \u0026#34;\u0026#34; ] ; then echo \u0026#34;Error: $*\u0026#34; fi cat \u0026lt;\u0026lt; EOF Usage: $PROGNAME [OPTION ...] BB-TEAM-OR-USER-NAME Generate the list of the repositiories for given team or used Options: -h, --help display this usage message and exit -d, --debug set debug = true EOF exit 1 } debug=0 username=\u0026#34;undefined\u0026#34; if [ $# -eq 0 ] ; then echo Missing argument: BB user name or team usage fi while [ $# -gt 0 ] ; do case \u0026#34;$1\u0026#34; in -h|--help) usage ;; -d|--debug) debug=1 ;; -*) usage \u0026#34;Unknown option \u0026#39;$1\u0026#39;\u0026#34; ;; *) if [ \u0026#34;$username\u0026#34; = \u0026#34;undefined\u0026#34; ] ; then username=\u0026#34;$1\u0026#34; else usage \u0026#34;Too many arguments\u0026#34; fi ;; esac shift done if [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then . ~/.ssh/bitbucket-token-work.secret fi if [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo \u0026#34;You must export variables BBUSER and BBPASSWORD\u0026#34; exit 2 fi export CREDS=\u0026#34;$BBUSER:$BBPASSWORD\u0026#34; # Display info about the user echo Logged on as user curl -s -u $CREDS \u0026#34;${BB}/user\u0026#34; \\ | jq \u0026#39;{account_id, uuid, username, display_name, snippets: .links.snippets.href, self: .links.self.href}\u0026#39; curl -s -u $CREDS \u0026#34;${BB}/teams/${username}\u0026#34; \\ | jq \u0026#39;{ uuid, username, display_name, snippets: .links.snippets.href, self: .links.self.href}\u0026#39; \\ \u0026gt; ${username}-team-info.json echo Team info - see ${username}-team-info.json # Produce list of the repositories in format slug=REPO ENTRIES=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username} | jq .size) PAGELEN=$(curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username} | jq .pagelen) PAGES=$(expr $ENTRIES / $PAGELEN \u0026#34;+\u0026#34; 1) echo The TEAM $username has $ENTRIES repos for i in $(seq 1 $PAGES) do curl -s --user $BBUSER:$BBPASSWORD ${BB}/repositories/${username}\\?page\\=${i}\\\u0026amp;pagelen\\=${PAGELEN} \u0026gt; ${username}-REPO-${i}.json done for i in $(seq 1 $PAGES) do jq \u0026#39;.values[].links.clone[].href\u0026#39; \u0026lt; ${username}-REPO-${i}.json | grep -v https | sed \u0026#39;s/\u0026#34;//g\u0026#39; \u0026gt; ${username}-${i}.repos done rm -f ${username}-REPO-*.json # Make sure the file is empty/none - we will append rm -f ${username}.bb-repos cat ${username}-*.repos \u0026gt;\u0026gt;${username}.bb-repos rm ${username}-*.repos echo See ${username}.bb-repos It also generates the ${org}-team-info.json file with basic information about the team:\n{ \u0026#34;uuid\u0026#34;: \u0026#34;{c4xxxxxxxxxxx10d612}\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;thinkwrap\u0026#34;, \u0026#34;display_name\u0026#34;: \u0026#34;Pivotree\u0026#34;, \u0026#34;snippets\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/snippets/%7Bc4xxxxxxxxxx10d612%7D\u0026#34;, \u0026#34;self\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/teams/%7Bc4xxxxxxxxxxx10d612%7D\u0026#34; } Example of the run:\n➜ ./bb-repos-info-json.sh pivotree_h3 Logged on as user { \u0026#34;account_id\u0026#34;: \u0026#34;557058:xxxxxxxxx-e6ce68c69dda\u0026#34;, \u0026#34;uuid\u0026#34;: \u0026#34;{d8-xxxxxxx-08}\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;\u0026lt;username\u0026gt;\u0026#34;, \u0026#34;display_name\u0026#34;: \u0026#34;Miro Adamy\u0026#34;, \u0026#34;snippets\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/snippets/%7Bd8-xxxxxxx-08%7D\u0026#34;, \u0026#34;self\u0026#34;: \u0026#34;https://api.bitbucket.org/2.0/users/%7Bd8-xxxxxxx-08%7D\u0026#34; } Team info See pivotree_h3-team-info.json The TEAM pivotree_h3 has 152 repos in 16 pages See pivotree_h3.bb-repos Automation # The script ./bb-repo-links.sh generates the information for all organizations:\nif [ -z \u0026#34;$BBUSER\u0026#34; ] || [ -z \u0026#34;$BBPASSWORD\u0026#34; ] ; then echo Using locally defined credentials from ~/.ssh/bitbucket-token-work.secret . ~/.ssh/bitbucket-token-work.secret fi for org in $(./bb-teams.sh ); do ./bb-repos-info-json.sh $org done NOTE\nThis was also published on our team blog post\n","date":"February 15, 2021","externalUrl":null,"permalink":"/posts/2021-02-15-bitbucket-list-repos/","section":"Posts","summary":"How to list repositories in Bitbucket # Use case:\nI want to maintain repositories in an organization in Bitbucket. To make sure I do not miss newly added ones, I want to use API access to retrieve the list of all repositories in the organization.\nSetup # Bitbucket requires a username and password to access the API. This information is stored in the environment variables BBUSER and BBPASSWORD. The BBPASSWORD should be an access token / app password defined in the App passwords section of the user settings:\n","title":"How to list Bitbucket repositories and users","type":"post"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/tags/asciidoc/","section":"Tags","summary":"","title":"Asciidoc","type":"tags"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/categories/best-practices/","section":"Categories","summary":"","title":"Best Practices","type":"categories"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/categories/documentation/","section":"Categories","summary":"","title":"Documentation","type":"categories"},{"content":"This blog post is a de-powerpointized version of a brownbag session in Pivotree. The goal was to increase awareness of tools and techniques for information / knowledge capture in the projects, specifically focusing on producing quality documentation so that everybody in project can access it and contribute to it, not only developers. We wanted to look at the tools that would allow engineers keep using their tools of trade (without impact on developer’s productivity) and at the same time make the information available without duplication of work to increase re-findability of information.\nWe are introducing standards, tools and best practices for documentation and suggesting workflow that can simplify and streamline the process of creating a documentation and keeping it up to date.\nNote: it was also published at our workgroup blog.\nWhy documentation is important # In commercial environment, quality (and often existence) of documentation is important factor in determining what will be the cost of maintaining the codebase.\nWhether or not the documentation is available / complete / up-to-date can greatly impact:\nwhether the code will be correctly used how fast it will be available for reuse / modification how efficient / dynamic will onboarding / transfer of people within the team work In OpenSource world quality and comprehensiveness of documentation is a matter of project survival. With all other things (code quality, functionality, community size etc) comparable or equal, the project that makes it easier to understand the code, has more examples and helps make the learning curve less steep, will have better adoption rate and much greater chance to attract the contributors and users. In the end, this will decide whether the project will live and prosper or gets abandoned.\nThere is another aspect. While documenting a system: we give it another look and create an \u0026ldquo;internal checkpoint\u0026rdquo; that helps to answer questions like:\nIs it really complete ? What is missing ? Are edge cases covered ? Does it do what it should do ? This can have a great impact on the development of a project and should be an ongoing process, not left for “afterwards” when the coding is done.\nWriting documentation is explaining the code to unknown audience. One can consider it an instance of a “Rubber Duck debugging” session without any particular problem on the table. It is very useful exercises and quite often it makes visible overlooked scenarios and generally improves quality of code by the simple process of giving it another look from a different angle, wearing a different hat than coders do.\nWhat makes a documentation good and/or useful # The criteria for good documentation we aim for is a documentation that:\nis up-to date is accessible to the proper audience (all project stakeholders) is it easy to extend / modify has its lifecycle defined and tied to project lifecycle is it easy to find: has high degree of re-findability Code vs Documentation: what we document # Documentation contains parts with different degrees of closeness to a project code.\nAt the closest end, there is documentation that lives inside the source code files. This type of documentation is focusing on details such as explaining purpose and functionality of functions, parameters, explanation of the details. It is crucial in the \u0026ldquo;forensic\u0026rdquo; / maintenance situation - debugging the code and searching for an answer to the question \u0026ldquo;why does this not work\u0026rdquo; ?\nWhile this type of documentation is extremely useful and important, we cannot limit our focus at this level. The problem here is that at this level of detail the documentation is rather hard to read: it is not clear where to start, where to go next - it does not tell a story and it\u0026rsquo;s structure is dictated by physical code structure.\nThis is where additional, higher level description comes into play: system description, explanation how does the subsystem / whole system work, what is a module architecture, what are interfaces between modules, subsystems.\nThis type of documentation covers information outside of scope of a single source file, but is still source code related. It includes examples of APIs, examples of proper use of the code. It should represent a logical view, that is different from the code structure.\nAt the highest level of abstraction from the code we have documentation of architecture and project design, user documentation, installation and project lifecycle documentation.\nAll this type of documentation needs to be represented / written in some form and exist is some place. Quite often, the different levels of documentation can be found in different places using different tools. I am trying to show why this is not the best approach and present tools and workflows that allow documentation and code coexit in the same place.\nWhere does your documentation live # There are two places where documentation can live:\nin the same source code repository as the code somewhere else There are several advantages of using the same repository as the source code:\nFirst, it is the audience - big part of the documentation is written by (current) developers for (future) developers. This way it can be managed together, using code version friendly tools. In order to do that, we need to use code version friendly formats - text based formats.\nSecond - using the same repository synchronizes release cycles of the documentation. It is much easier to update the CHANGELOG.md when it is right there and to make it part of the next commit than to remember to go to some Wiki and do it there. How many similar lines as the following one have you seen during your career ?\n... SOME CODE # TODO: Update the Release Notes in the Wiki - URL ... more code Which gets us to second location for the documentation: somewhere else - meaning \u0026ldquo;separate from the code\u0026rdquo;.\nElsewhere can include places like \u0026ldquo;in a Wiki\u0026rdquo; - which is not great to really unhappy places such as Word documents on a file share.\nThere are many issues with this approach: by going elsewhere for the documentation, we need to use separate credentials, loose the direct link to code. Some part of documentation (source code comments) still stays with the source, but other parts - the higher level - are now elsewhere. The \u0026ldquo;one source of truth\u0026rdquo; is lost and often documentation in Wiki contains different information than the actual code.\nWith \u0026ldquo;elsewhere\u0026rdquo; we get inherently different release cycles for project code and documentation: updating the documentation is decoupled from code changes and project releases which impacts the \u0026ldquo;up-to-dateness\u0026rdquo; of the information. It also makes the automation and CI/CD much more complicated.\nWe also get different search scopes: to find something, two searches are necessary - one over the source code and one over the documentation place.\nAs the information related to code lives in two places, we will not have a single source of truth: if there is an overlap and the one place does not agree with the other, there is a risk of using the wrong one. Transfer of information between two locations leads to unnecessary work.\nNote: with all the issues mentioned above, Wiki at least has a built-in mechanism of versioning and diff capability with change tracking and prevention of information loss / overwriting. A much worse situation is using separate word documents on file share - the binary format makes content comparison more complicated and file share is susceptible to overwrite / information loss. Where Wiki falls short is that it is \u0026ldquo;single threaded\u0026rdquo; - there is a single sequence of changes (albeit made by different contributors). In the code world, the typical situation is that we have multiple active branches representing (at minimum) current - deployed application, bug-fix branch (small changes with short release cycle) and future\nWith all that said, we can ask what is the main motivation of using the Wiki as a separate documentation store ? It is usually easy to edit (web interface with some form of WYSIWYG) and formatting capabilities of the Wiki compared to plain text inside the source code repository (headers, bullet points, tables, embedded pictures, links etc). An idea of accessing text based file in a Git repository and the developer\u0026rsquo;s prefered tool chain (that is command line oriented and quite technical) may seem at a first glance to be to complicated for non-developer members of the team: project managers, business analysts, product managers / stake owners.\nIn the next part we will show that if a proper format for a documentation file is selected, we can address both of these concerns without leaving the realm of the single source code repository. Let\u0026rsquo;s have a look at available documentation formats from a maintainability point of view and see how these can impact the user experience for content contributors.\nFormats - from maintainability POV # What makes document format \u0026ldquo;good\u0026rdquo; from maintainability perspective is that it must be simple and text based.\nSimilar to source code files.\nThis allows easy diff creation and versioning and most importantly, easy merging when different versions of code (and documentation) are being worked on in parallel.\nUnfortunately, pure text is not visually appealing and lacks lots of features such as a standard way to embed images and structure parts of text (such as heading). There is a text based format that has all these features and more but it is very impractical for manual editing - the HTML.\nThe middle ground between plain text and full presentation capable HTML is markup - a standard of formatting plain text file so that it can be easily transformed into HTML representation. Even better, all major source control platforms - Github, Bitbucket and Gitlab - support rendering the markdown files as nicely formatted HTML with headers, links, tables and embedded pictures while allowing editing the source form of the file in the browser. The word \u0026ldquo;markup\u0026rdquo; indicates how it works: there are special, designated characters or words that indicates the formatting or structure of a piece of text - e.g. indicating header, table or embedded image - it marks it up for presentation.\nThe result is good looking, easy to version and easy to edit documentation files.\nConsiderably worse choice from maintainability point of view are binary proprietary formats - e.g. most famous one would be Word. They are either binary (doc), but even if not, the internal XML based format is not suitable for neither comparing nor editing without proprietary tools. Using the open source alternatives does not help - they pose the same problem and the fact that one does not have a commercial license to use them does not help either.\nAbsolutely worst format from maintainability point of view are systems storing the documentation in a database, which essentially turns a document into a proprietary blob and then hides it inside a much bigger proprietary blog, accessible only through a dedicated proprietary interface.\nSo the best bet is selecting a markup format that is simple enough to be easy to learn for non-technical users, expressive enough to produce great looking rendered documentation and with tool support allowing in-place editing on Github/Bitbucket, tools for advanced user as well as support for automation of documentation rendering. The rendering does not necessarily need to be only HTML - many markup toolchains can produce PDF or ebook format such as ePub. These will be the criteria we will use to select best markup format for our use case\nMarkup formats parade # At the end of 2020, we can safely say that the big 3 worth looking at are:\nMarkdown AsciiDoc RestructuredText with LaTex as honorable mention.\nWe were quite considering it seriously because even if technically it is a markup, but it\u0026rsquo;s capabilities and complexity is in a different league. It shines for creating scientific articles with complex mathematical formulas and beautiful exact typography and the whole toolchain is targeting a very different audience and use cases.\nHere are few examples that can be a small peek into how powerful (and complex) LaTex markup is:\nSide-by-side source/rendered:\nA snippet of the source .. that renders this result Markdown # Markdown is by far the most popular markup format in use. It is also the simplest / easiest to use from the big 3. It has widest tooling support - most IDEs and major editors support preview mode (e.g. Visual Studio Code, PyCharm, Atom) - either OOTB or via plugins. Not surprisingly, there are lots of generators that take one or more markdown files and produce good looking web pages or web sites. It is well supported by CI/CD pipelines and most use cases is focused on producing HTML output\nAmong disadvantages of Markdown is lack of standardization - there are dialects and supported features in different toolchains may differ. One of the dialects seems to be approaching \u0026lsquo;standard\u0026rsquo; status - GFM also known as Github Flavored Markdown, which together with \u0026lsquo;Material theme\u0026rsquo; enjoys great popularity among users. The second disadvantage is being less expressive / less powerful than the others - a consequence of being simpler\nFew pointers\nhttps://markdown-it.github.io/ https://www.markdownguide.org/cheat-sheet/ https://guides.github.com/features/mastering-markdown/ AsciiDoc # AsciiDoc (https://asciidoc.org/) is format used by toolchains that many book authors use to author and produce eBooks and printed - OReilly among the most notable ones see (documentation on Atlas)[https://docs.atlas.oreilly.com/writing_in_asciidoc.html]. AsciiDoc has many features well suited for larger projects - e.g. support for glossaries, which is no surprise as it started as a markup lightweight alternative to DocBook - XML based format for book authoring.\nThe best known tool for AsciiDoc is AsciiDoctor - check its functionality and some more details on differences between AsciiDoc and Markdown here, and here. The second link shows few of the \u0026ldquo;killer features\u0026rdquo; of AsciiDoc for code documentation\ne.g. annotation of the code snippet rendered as numbered callouts: or treatment of the tables:\nRestructuredText # The last of the big three is coming from and is focused on Python and programming languages documentation. It has excellent capabilities to combine documentation extracted from source files - (in Python world \u0026ldquo;docstrings\u0026rdquo;) with the text only files into a coherent, larger body of information. It was originally created as the format for Docutils documents and it\u0026rsquo;s initial release dates back to 2002 - so it is older than Markdown.\nIt\u0026rsquo;s superpowers are in the area of inweaving the code and the text, with extracts from the source files. It is very easy to include partial content of the source code directly into the text, create a table of content or well defined extensibility. It\u0026rsquo;s \u0026ldquo;native\u0026rdquo; toolchain is called Sphinx and it\u0026rsquo;s showcase is ReadTheDocs - documentation hosting site based on Sphinx but also supports Markdown. Another good example of RestructuredText capabilities is anaconda documentation or sphinx documentation\nRestructured text is more complex and unfortunately more fragile than the previous two formats. It is quite easy to write invalid markup and I have personally run several times into weird formatting issues (unlike with Markdown or AsciiDoc). After using it for over 1 years for personal projects I gave up and switched to Markdown - and I was not alone that ended up doing so.\nIt is also least popular and mostly unknown outside of the Python community.\nHere is side by side comparison of the syntax similarities and differences between these formats.\n\u0026hellip; and the winner is: # Markdown. The ease of use, simplicity, wide toolchain support and being the \u0026ldquo;native\u0026rdquo; markup for all three Git hosting sites (which we all use for different sides of the business).\nAs for toolchain, we have selected two options: MkDocs with Material Theme and Gatsby.\nAuthoring - as easy as Wiki # The way you write the documentation using Markdown, depends on what kind of role you play in the projects. For developers, the great news is that you keep using whatever tools you are happy with: any major editor (Visual Studio Code, Atom, Sublime Text, vim, emacs, Notepad++ - etc) supoort Markdown, in many cases including the preview functionality - either directly of through plugins. The documentation is simply a set of files living under the ./docs folder in your repository.\nIf you are not a developer and do not really know all the details regarding git, cloning, branches and pull requests, no worries: there is a Wiki-like way to contribute and document everything.\nFirst get access to the repository on Github, Bitbucket or Gitlab - whatever your project uses. Then simply find the file in the repository and open it.\nYou will notice that it renders as a nice formatted web page (this is the preview mode).\nIn order to change the file, you need to switch to Edit mode.\nThe browser now offers you a \u0026ldquo;source\u0026rdquo; version of the file in Markdown.\nMake the changes you want and save the changes by making commit. There are two ways to save: either by simply adding the new version of the file to the repository history or by creating a pull request - a separate area where you change will be kept, allowing somebody to review it and merge it with the rest of the changes other developers may be doing.\nIf you are new to this, here are some pointers:\nhttps://www.atlassian.com/git/tutorials/source-code-management https://bitbucket.org/blog/edit-your-code-in-the-cloud-with-bitbucket https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/about-pull-requests https://docs.gitlab.com/ee/topics/gitlab_flow.html The main point here is that from a content creator experience point of view, this gives you very similar tools as Wiki without disadvantage of working on a separate system, away from development workflow. Your documentation will become an integral part of the development flow and will not drift or diverge because the documentation writers are separated from the codebase and unaware of the latest changes.\nOrganization of the Doc and Code: MkDocs # The above flows - Web based or developer oriented - were addressing the process of working with a single file. Most project will have many documentation files. They are useful on their own, but there is a simple way to define a navigational menu and turn them to dynamically generated web site with left side navigation bar and right-side file structure preview. This is what MkDocs does for us.\nTo make repository work with MkDocs, two things are necessary:\nput the Markdown files under ./docs folder add file mkdocs.yml to the root of the project that defines configuration of the documentation Here is an example of a config file\nsite_name: Reference Architecture for $PRODUCTNAME repo_url: https://bitbucket.org/pivotree/$PRODUCTNAME-ref-arch/src/master/ repo_name: $PRODUCTNAME-ref-arch site_description: $PRODUCTNAME Reference Architecture - Infrastructure Documentation site_author: miro.adamy@pivotree.com copyright: (c) 2020 Pivotree - https://pivotree.com/ nav: - Home: index.md - Environments: - Staging: STAG.md - Production: PROD.md - Dev/QA: DEV.md - Modules: - Module 1: module-demo-1.md - Module 2: module-demo-2.md - Examples: - Minimal: example-minimal.md - Typical: example-typical.md - Everything: example-everything.md - About this Documentation: - Intro to MkDocs: mkdocs/about.md - Markdown Demo: mkdocs/markdown-demo.md - Macros Demo: mkdocs/macros-demo1.md # - Diagrams: plantuml/diagrams.md theme: name: material markdown_extensions: - admonition - codehilite - footnotes - meta - toc: permalink: True - sane_lists - pymdownx.arithmatex - pymdownx.emoji: emoji_index: !!python/name:materialx.emoji.twemoji emoji_generator: !!python/name:materialx.emoji.to_svg - pymdownx.superfences - pymdownx.tasklist: custom_checkbox: true - pymdownx.tabbed - pymdownx.tilde - pymdownx.magiclink - pymdownx.details plugins: - search - macros: include_dir: . extra: price: 12.50 company: name: Pivotree address: March 450 website: https://pivotree.com/ It contains 5 parts:\nheader - name of the site navigational structure - which files create site and how theme markdown extensions plugins (note the include_dir directive) extra data (can be used in parameters) Here is the source code organization:\nNavigation: SRC =\u0026gt; Rendered # The generated site takes the navigation part of mkdocs.yml:\nand renders a dynamic menu out of it.\nThe whole layout of the site is defined by the navigation and the used theme. It is material theme for MkDocs that works in the background and renders the 3-column view with navigation on the left, content in the middle and structure of currently displayed document in the right column\nDocumentation Generation and Hosting # The process of transformation of the Markdown files to a website can be fully automated using CI/CD pipelines in each of the major hosting sites. The best support (IMHO) has Gitlab where this is an OOTB feature:\nThis is .gitlab-ci.yml that generates HTML sites accessible as Gitlab Pages attached to the repository. The great advantage of Gitlab is support for private Gitlab pages for private repositories, which simplify setup for authentication / authorization.\nimage: python:3.8-buster before_script: - pip install mkdocs \u0026#39;mkdocs-minify-plugin\u0026gt;=0.2\u0026#39; - pip install \u0026#39;mkdocs-git-revision-date-localized-plugin\u0026gt;=0.4\u0026#39; \u0026#39;mkdocs-awesome-pages-plugin\u0026gt;=2.2.1\u0026#39; \u0026#39;mkdocs-macros-plugin\u0026#39; # Add your custom theme if not inside a theme_dir # (https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes) # - pip install mkdocs-material pages: script: - mkdocs build - mv site public artifacts: paths: - public only: - master Similar setup works for Github by generating the website into a second, dedicated \u0026ldquo;published\u0026rdquo; Github pages repository. Unlike in the Gitlab case, all Github pages are public. For more information, refer to this\nAnother option is dedicated hosting site for MkDocs documentatio ReadTheDocs which also supports Sphinx and RestructuredText\nAnd of course, there is always an option to use mkdocs build and copy the generated static site from ./public site to the hosting provider - e.g. an S3 bucket.\nSingle vs Multi-repository projects # In cloud native projects, it is very rare nowadays that all project code is stored in a single repository. With microservices, serverless, infrastructure as a code, GitOps etc we usually end up with quite a few different repositories. We can use the techniques above for documenting everything related to one repository - e.g. one microservice - but when it comes to documentation involving multiple components, we have a similar issue as with source code file vs documentation files: we have to put this doc files outside of the component repositories.\nEach of the repositories internally uses it\u0026rsquo;s MkDocs structure and has its own mkdocs.yml file. For the documentation that does not belong to any particular component, we create another MkDocs repository that plays three roles:\nholds all documentation for all inter-modular parts holds main navigational tree and links to submodule specific navigation checks out all component modules as git submodules As a proof of concept, we use this technique for documentation of the DIVE2 machine learning platform.\nHere is the \u0026ldquo;top level\u0026rdquo; repository:\n➜ tree -L 2 . └── dive-documentation ├── CHANGELOG.md ├── README.md ├── dive-data-manager ├── dive-data-manager-api ├── dive-data-schema-svc ├── dive-infra ├── dive-job-manager ├── dive-model-manager ├── dive-prg-control-svc ├── dive-sgm-control-svc ├── dive-sgm-lib ├── dive-sgm-svc-template ├── dive-sls-batch ├── dive-user-mgmt ├── docs ├── document_server.sh ├── local-links.md ├── mkdocs.yml ├── pvt-python-commons ├── pvt-python-rest ├── pvt-sgm-color-norm-svc └── tr-sgm-duplicates-svc 18 directories, 5 files and here is the subset of the mkdocs.yml file:\nsite_name: DIVE2 joint Documentation repo_url: https://bitbucket.org/pivotree_h3/dive-documentation/src/master/ repo_name: dive-documentation site_description: DIVE2 Documentation site_author: miro.adamy@pivotree.com copyright: (c) 2020 Pivotree - https://pivotree.com/ nav: - Home: index.md - Infra: dive-infra.md - Data: Manager: data-manager.md Manager API: data-manager-api.md Schema: data-schema-svc.md - Job Manager: job-manager.md - Model Manager: model-manager.md - User Management: user-mgmt.md - Prg control: prg-control-svc.md - Sagemaker: - Sagemaker Control: sgm-control-svc.md - Sagemaker Lib: sgm-lib.md - Service Template: sgm-svc-template.md - Duplicates Svc: tr-sgm-duplicates-svc.md - Color Normalization: pvt-sgm-color-norm-svc.md - Batch: sls-batch.md - Libs: pvt-python-commons: pvt-python-commons.md pvt-python-rest: pvt-python-rest.md theme: name: material markdown_extensions: ... DELETED ... plugins: - search - macros: include_dir: . The rendered website reaches into the submodules and displays information from services in one consistent unit, combined with additional information about architecture, module relations ect. All this without duplication or requirements for the service team to work outside of their area of focus.\nThe mechanics is quite simple. The main menu - nav structure - refers to the files representing the submodule entry points. These files are located in the docs directory of the \u0026ldquo;roof\u0026rdquo; repository.\n➜ dive-documentation git:(master) tree docs docs ├── data-manager-api.md ├── data-manager.md ├── data-schema-svc.md ├── dive-infra.md ├── index.md ├── job-manager.md ├── model-manager.md ├── prg-control-svc.md ├── pvt-python-commons.md ├── pvt-python-rest.md ├── pvt-sgm-color-norm-svc.md ├── sgm-control-svc.md ├── sgm-lib.md ├── sgm-svc-template.md ├── sls-batch.md ├── tr-sgm-duplicates-svc.md └── user-mgmt.md 0 directories, 17 files How are these files hierarchically arranged is decided in the nav part of the YML file:\nEach of this file contains one or more include directives, which are operating from the top directory of the repository and have therefore access to any submodule markdown files:\n➜ dive-documentation git:(master) cat docs/model-manager.md {% include \u0026#39;dive-model-manager/README.md\u0026#39; %} If the structure of the submodule is more complex, the \u0026ldquo;module file\u0026rdquo; can contain more directives or links.\nWhen all this is put together, we get a combined, unified view of the system documentation with all submodules included. It is fully in the hands of the services team what the service documentation looks like and it is fully in the hands of the documentation repository maintainer which of those will be published and where in the navigation tree.\nOther tools: # During last couple of months, we have looked at and used several other systems related to documentation generation\nAntora - Asciidoc based, multi-repo system Hugo - Go template based Markdown generator Jekyll / Hyde - another generator, Ruby based but this post is getting way too long, so I will get back to some of them in the future.\nThere is certainly no shortage of available generators and solution - check the dedicated site. My colleague wrote a continuation with detailed case study on one of them in this blogpost\n","date":"November 23, 2020","externalUrl":null,"permalink":"/posts/2020-11-23-documentation-multi-repo/","section":"Posts","summary":"This blog post is a de-powerpointized version of a brownbag session in Pivotree. The goal was to increase awareness of tools and techniques for information / knowledge capture in the projects, specifically focusing on producing quality documentation so that everybody in project can access it and contribute to it, not only developers. We wanted to look at the tools that would allow engineers keep using their tools of trade (without impact on developer’s productivity) and at the same time make the information available without duplication of work to increase re-findability of information.\n","title":"Documenting multi-repository projects","type":"post"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/tags/markdown/","section":"Tags","summary":"","title":"Markdown","type":"tags"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/tags/markup/","section":"Tags","summary":"","title":"Markup","type":"tags"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/tags/mkdocs/","section":"Tags","summary":"","title":"Mkdocs","type":"tags"},{"content":"","date":"November 23, 2020","externalUrl":null,"permalink":"/tags/restructuredtext/","section":"Tags","summary":"","title":"Restructuredtext","type":"tags"},{"content":"","date":"August 10, 2020","externalUrl":null,"permalink":"/categories/architecture/","section":"Categories","summary":"","title":"Architecture","type":"categories"},{"content":"","date":"August 10, 2020","externalUrl":null,"permalink":"/tags/ecommerce/","section":"Tags","summary":"","title":"ECommerce","type":"tags"},{"content":"","date":"August 10, 2020","externalUrl":null,"permalink":"/tags/iaac/","section":"Tags","summary":"","title":"IaaC","type":"tags"},{"content":" Many shapes of Architecture # According to the wise people, an architecture is the shared understanding that the expert developers/system builders/maintainers have of the system design. It\u0026rsquo;s purpose is to maximize the probability that the decisions you have to make early in a project are the right ones. It is sort of a blueprint for the future system and captures parts, relations, boundaries, constraints.\nIn our business (we build and run environments and solutions for eCommerce, data management and other business activities of our customers), an important subtype of architecture is Reference Architecture. It is an architecture that serves both as a capture of best practices for a particular business case as well as a living, evolving template for creating new instances of that type of an environment. Both best practice as well as evolving features are important: the reference architecture (RA) serves as knowledge gathering in the ever changing world of cloud. As new features of AWS or Azure come, the RA needs to absorb them to incorporate latest advances and to use the best price / performance options available.\nArchitecture can take many physical forms. Traditionally, back in the waterfall age, it used to be a long Word document, a collection of Visio drawings or combination of both. Eventually Word was replaced by Google Docs and/or Confluence, but the same idea stayed: the prose written for humans that use manual processes to transform the prose to instances of a system, usually using cloud management console or some other tool. With the arrival of Cloudformation and Terraform, the manual process got scripted which helped repeatability during the environment creation phase, but it also introduced a new challenge: a gap between code living in version control and documentation living in a Wiki. These two separate representations of the same idea were stored in different places, requiring different tools and different credentials - despite being managed and worked on by the same people. As a natural consequence, the documentation often got out of sync with the code and instead of making understanding better and explaining / documenting, it added confusion and stopped being useful.\nSome people say the special dedicated tools that hold both are the answer. Such a tool would provide a single place to hold all the information, allow creating diagrams, add documentation and maintain or generate the code. I am a bit sceptical when it comes to these kinds of solutions. I have seen good partial solution in the past (e.g. Enterprise Architect) that were delivering value, but they were limited to subset of languages and notations - e.g. UML diagrams and Java/C++ or object oriented languages. I am not aware of any tool I would consider full scale replacement for good documentation plus code. Some are promising - e.g. Cloudcraft plugin from Anton Babenko. I imagine this can be an excellent option for a startup or small company, but does not allow us enough flexibility to fit within existing tools and backend systems we have.\nRest of this blog entry will describe one possible way we are trying to overcome the documentation / code gap by using open standards, opensource tools and adhering to documentation as a code philosophy.\nAs a result, we define Reference Architecture as code artifact - repository that contains both executable description (Terraform Code) as well as all the documentation explaining decisions, options and alternatives using best practices such as WAF, adapted to company and customers special needs - e.g. enforcing / standardising naming, tagging, policies and in general capturing knowledge about the system built.\nSelecting the format # The documentation format should satisfy these requirements\nmust be file oriented (not living in database) =\u0026gt; it can goes with terraform code to same repo must be Git friendly = allow good versioning and comparison must be easy to work with for developers must be expressive enough to allow formatting for pleasant Web reading experience (unlike e.g. man or pod) must allow easy way to generate documentation for set of interconnected pages must be open, well supported with good ecosystem for tools and automation must be CI/CD friendly (using pipelines in Bitbucket/GitHub/Gitlab) We have ended up with a shortlist of three main contenders:\nMarkDown with MkDocs / Material Theme AsciiDoc RestructuredText with Sphinx After evaluating each (details of this evaluation will be published in a separate post) we ended up selecting the MarkDown.\nThe main three reasons why we ended up selecting MarkDown were:\nfamiliarity - Markdown is best known format, zero learning curve MkDocs is Python based and with Material Theme competes very well with Sphinx generated sites extensibility - using Macros module allowed to solve the file include problem Reference Architecture with Markdown and MkDocs # To add the documentation-as-a-code to the Terraform repo (the actual code), there is very little to do. Absolute necessary are only two files:\n./mkdocs.yml - defines the structure of the navigation and MkDocs configuration ./docs/index.md - default directory and one Markdown file (the name can me different than index.md) It is usually a good idea to add requirements.txt file for those users who prefer to install MkDocs locally and a shell script that runs MkDocs in Docker to the root:\ndocker run --rm -it -p 8000:8000 -v $(pwd):/docs miroadamy/mkdocs-material $@ and requirements.txt\nmkdocs mkdocs-material mkdocs-minify-plugin\u0026gt;=0.2 mkdocs-git-revision-date-localized-plugin\u0026gt;=0.4 mkdocs-awesome-pages-plugin\u0026gt;=2.2.1 mkdocs-macros-plugin diagrams The last dependency is optional - only if you plan to use a Python based diagramming tool later on.\nThe above structure is for the documentation. The Terraform code lives in folders that are dedicated to environments or variants of environments. The general structure of the Terraform code is:\n./ - PROD = named environment - UAT = named environment - UAT-HA = named variant - DEVQA = named environment - modules/ - database/ - local module for RDS provisioning - vpn/ - local module - examples/ - minimal/ = example of a minimal environment - everything = the HA top environment example - typical/ = example of most common use case - typical-mysql = example specific to a particular database We use three kind of Terraform modules:\n* platform library * community modules * local RA specific modules The most useful are Platform Library modules. These are internal, mostly closed source modules that provide packaged templates for making sure that environments we build for our customers contain all necessary security a best practices features from the ground up. For example, proper and consistent tagging of the resources is crucial for proper monitoring and cost reporting, policies are super important for security, logs processing for integration with the monitoring tools CloudOps team uses and general structure, default variables and locals to make sure that the account works well inside our AWS organization hierarchy and Pivotree workflow.\nPlatform library is maintained by dedicated internal team and while it is pretty comprehensive, it does not cover everything. We often adapt community modules, add our own extensions / bug fixes / documentation and republish the fork as opensource back to the community.\nThe local RA modules often are \u0026ldquo;second degree modules\u0026rdquo; - the modules that are using other modules. We use them for making sure there is good balance between consistency among environments and respecting the DRY (don\u0026rsquo;t repeat yourself) design principle.\nEach of the Terraform folders for environment, module or example can have it\u0026rsquo;s own docs/ subfolder where the environment/module/example specific information can reside. The main navigation can easily point to these pages and provide a consistent, global documentation tree.\nThe key feature for good user experience is ability to include both Markdown fragments and code files into the compiled documentation - this is provided by include macro added in the mkdocs.yml combined with a \u0026ldquo;proxy\u0026rdquo; markdown files that have the name of the environment/module or example they represent and simply include the main Markdown file for that environment\nThe file for production environment - ./docs/PROD.md (the terraform code for production is in the ./PROD/ folder)\n{% include \u0026#39;PROD/docs/README.md\u0026#39; %} Here is an example - a starter template how such architecture can look like\nJust the documentation portion:\n➜ aaac-starter-template tree . ├── CHANGELOG.md ├── DEV │ └── docs │ └── README.md ├── PROD │ └── docs │ └── README.md ├── README.md ├── UAT │ └── docs │ └── README.md ├── docs │ ├── DEV.md │ ├── PROD.md │ ├── UAT.md │ ├── example-everything.md │ ├── example-minimal.md │ ├── example-typical.md │ ├── index.md │ ├── mkdocs │ │ ├── about.md │ │ ├── macros-demo1.md │ │ ├── markdown-demo.md │ │ └── snippet.md │ ├── module-demo-1.md │ └── module-demo-2.md ├── document_server.sh ├── examples │ ├── everything │ │ └── README.md │ ├── minimal │ │ └── README.md │ └── typical │ └── README.md ├── mkdocs.yml ├── modules │ ├── demo-1 │ │ └── docs │ │ └── README.md │ └── demo-2 │ └── docs │ └── README.md └── requirements.txt 17 directories, 26 files This is how the navigation in the table of content looks like in the source form:\nand the rendered form:\nTerraform code organization # This topic deserves deeper discussion, but at the high level, Terraform does not care how many files is there in the \u0026ldquo;project\u0026rdquo; (which must be located in single directory), what are the file names (as long as they have .tf extension) or how is the content distributed among them.\nWe are using our own adopted version of a naming/content allocation scheme for Terraform files that looks looks like this (this is an example that uses Platform library and most of the files are \u0026ldquo;clients\u0026rdquo; of some module):\nmain.tf - the main functionality providers.tf - configuration of the AWS provider (locked version) and others version.tf - lock terraform version outputs.tf - all output produced variables.tf - declaration of all variables without default values pivotree-variables.tf - company-specific variables used for integration across sales, app services and ops locals.tf - the local definition - mainly for consistent tagging init.auto.tfvars - the predefined values of the variables with comments security-groups.tf - explicit definition of all used SG (optional) AWS-RESOURCE.net - depending on module, additional files for AWS resources (ELB, RDS, EC2 etc) docs/README.md or README.md - local documentation for this set of files only Here is an example of the Reference architecture repository with one module, one example and DEV environment containing the code for Terraform:\n. ├── CHANGELOG.md ├── DEV │ ├── docs │ │ └── README.md │ ├── init.auto.tfvars │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ ├── pivotree-variables.tf │ ├── providers.tf │ ├── security-groups.tf │ ├── variables.tf │ ├── version.tf │ └── vpc-net.tf ├── PROD │ └── docs │ └── README.md ├── README.md ├── UAT │ └── docs │ └── README.md ├── docs │ ├── DEV.md │ ├── PROD.md │ ├── UAT.md │ ├── example-everything.md │ ├── example-minimal.md │ ├── example-typical.md │ ├── index.md │ ├── mkdocs │ │ ├── about.md │ │ ├── macros-demo1.md │ │ ├── markdown-demo.md │ │ └── snippet.md │ ├── module-demo-1.md │ └── module-demo-2.md ├── document_server.sh ├── examples │ ├── everything │ │ └── README.md │ ├── minimal │ │ └── README.md │ └── typical │ ├── README.md │ ├── init.auto.tfvars │ ├── locals.tf │ ├── main.tf │ ├── outputs.tf │ ├── pivotree-variables.tf │ ├── providers.tf │ ├── security-groups.tf │ ├── variables.tf │ ├── version.tf │ └── vpc-net.tf ├── mkdocs.yml ├── modules │ ├── demo-1 │ │ ├── docs │ │ │ └── README.md │ │ ├── init.auto.tfvars │ │ ├── locals.tf │ │ ├── main.tf │ │ ├── outputs.tf │ │ ├── pivotree-variables.tf │ │ ├── providers.tf │ │ ├── security-groups.tf │ │ ├── variables.tf │ │ ├── version.tf │ │ └── vpc-net.tf │ └── demo-2 │ └── docs │ └── README.md └── requirements.txt 17 directories, 56 files Repository layout - or what belongs where # At this stage, we have quite a few folders or locations, both for the documentation as well as for the Terraform source code, so the natural question is: what should be placed where.\nThere are several ways how to address this, but the most important rule that should be kept in mind is:\npick ONE strategy that works for your process/way of thinking document it stick to it Here is what we are currently at:\nFirst: modules. This folder is often empty and when it is not empty, it should contain internal modules. These are reusable ways how to build part of the solution from other modules (public or private) or from resources. These are potential incubators for the new library modules. It is very important to pay attention to variables and outputs of the module, as these will determine its usability.\nThe documentation of the module should focus on details about variables (module parameters) and module outputs, default values as well as contain examples of what gets built.\nNext: examples. This is the core of Architecture as a Code - both on code as well as on documentation side. If there are variants of the architecture, there should be examples for each. An example is like a build for a non-existing project or a fictional customer. Examples should have good names and their documentation should describe the use case and decision criteria when the example is a good solution. At minimum, there should be 3 examples, named minimal, everything and typical.\nIf the architecture repository contains internal modules, there should be enough examples for each module.\nLast - the environment folders - UAT, PROD, DEV - should contain adapted examples of the build for a particular project. These are (from architecture point of view) transient folders as they will \u0026ldquo;grow and die\u0026rdquo; many times during the architecture lifecycle.\nReference Architecture Lifecycle # The main purpose of reference architecture is to support reuse and consistency between repetitive builds of the environments, while providing an easier way to extract changes, updates and best practices related to environment/cloud and tools evolution.\nThe simplest approach is to start a new build with a detached copy of the latest version of a RA repository. This is very easy and fast but makes later consolidation harder and usually results in consolidation never happens. At the end, there is set of snowflake repositories with no easy way to compare them or see their evolution path.\nBetter approach is using 2 repositories: a Project repository and an Architecture repo.\nStart with shallow cloning of the Architecture repository using architecture as origin name:\ngit clone --depth=1 --origin architecture ARCHITECTURE_REPO_URL Then create empty repository for the project in the Bitbucket/Github/Gitlab and add it as remote repository to the architecture clone:\ngit remote add origin PROJECT_REPO_URL The starting point of the new environments will be the current (develop) state of the architecture repo. Let\u0026rsquo;s assume the project name is RA_DEMO.\nWe will be working with multiple local branches that will be synchronized with the remote branches in these two repositories:\ndevelop =\u0026gt; origin/develop - environment definition in progress master =\u0026gt; origin/master - environment release state RA_DEMO =\u0026gt; architecture/PROJECTS/RA_DEMO To set it up:\ngit checkout master git push -u origin/master git checkout -b develop git merge archirecture/develop git push -u origin/develop git checkout -b RA_DEMO git push -u architecture/PROJECTS/RA_DEMO Main work will be happening in the develop branch, pushing the changes to origin/develop.\nThis means creating folders for ENV, adding Terraform code and documentation, testing documentation locally, running the code and adjusting.\nWhen the environment and documentation reaches tested state, we merge to master and push to project repository, where (eventually) the CI/DC pipelines will run and deploy the infrastructure.\nImportant thing to keep in mind is avoiding reformatting and large content re-arrangement which would complicate the next phase.\nWhen the environment is ready, we may end up with some changes or additions under ./modules or ./examples that are worthy of keeping as part of next builds based on this reference architecture. This is where the reintegration step comes into place.\nReintegration - project side # The goal of this phase is to make sure that worthy additions and improvements will be kept for the future builds.\nIt starts all by switching to RA_DEMO branch and merging the state we need to integrate:\ngit checkout RA_DEMO git merge master Usually, the details of the build environment are of little interest for the architecture. We can remove the ENV folders, add more documentation or better details while working on the RA_DEMO branch, producing one or more commits on this branch. All this commit should be local commits - do NOT push to architecture yet. Sometimes we may want to consider making a ENV build a new example\ncopy the TF code under ./examples, name it accordingly and update documentation / remove customer specific data. Sometimes we discover issues that should be addressed on the architecture level. Adding them to backlog.md is great way that they will be available for the maintainer of the RA repo.\nWhen the state of the architecture is in desired state, we can squeeze the commits to single commit using interactive rebase (see this for more details)\nAfter rebase, we can push the RA_DEMO to architecture remote:\ngit push and create a pull request for Architecture repo, to merge the PROJECT/RA_DEMO to develop.\nReintegration - architecture side # Second part of the reintegration happens completely in the Architecture repo, often by different person / team.\nClone the Architecture repo, switch to newly added PROJECT/RA_DEMO branch, review the addition.\nEvery change should be tested and independently validated. Ideally the architecture team adds dedicated tests for the new examples and more documentation, reviews backlog.md for list of issues / improvements suggested and creates tickets based on this information.\nIf everything is OK, increase version of the RA and merge to develop - to make it available for next iteration.\nThe starter template of the reference architecture using the above approach is available at my Github\nROI consideration # Creation and maintenance of the reference architecture is a non-trivial investment of time and resource. Not always this kind of effort is warranted. From our experience, here are some decision criteria when considering standardization and using this approach:\nhow many environments will be created during the next month / quarter ? RA and AaaC is less useful for small number of builds over longer periods of time what is the platform complexity ? For highly complex platforms with complex dependencies and long implementation cycle, it makes more sense focus on smaller building blocks rather than on full RA what is the speed of change for the platform ? Every major release (and often minor release as well) will require updating and re-testing the RA. For fast changing environment, this can be too expensive what is the customer requirements variability ? If there are huge differences between the builds, the RA will need to contain large number of examples and variants which will make maintenance and testing more costly. The ideal candidates for the AaaC / RA DevOps cycle are small to medium sized solutions with small number of variants, with customers requirements being similar enough to fit into 3-4 cases and with large enough number of deployments for a platform version that allows good test coverage.\nDiagrams Markdown Friendly Way # The traditional way how to create diagram and add them to the documentation is:\nuse an external tool - either a local one (Omnigraffle, Visio) or an online tool (LucidChart, Draw.IO) save source of the diagram somewhere (local drive or cloud) export the image rendering of the diagram to some image format (e.g. PNG) link the image to your documentation While this is easy and convenient way of doing things with very low barrier of entry, there are several disadvantage I\u0026rsquo;d like to point out\none must have the same version of editing software - on a proper platform if local. The challenges of sharing Omnigrafle source with Windows users (or Visio with Linux users) are non-trivial. For online tools, one must have access / license to the software. the native format is not living in the same place as the documentation - unless one uses local tools (which brings platform dependency) and life cycles of the documentation and diagrams are separate. This violates the original intention of keeping lifecycle of code and documentation together, and diagrams are fundamental part of the documentation native format is impossible to properly version control. As a consequence of the previous point, there is no easy way to tell differences between various versions of the diagram from the source and image. it is very hard to automate the rendering part to get e.g. different resolutions of the images for different media Binary Editor Alternatives # I\u0026rsquo;d like to showcase / demo two alternatives to visual GUI editors that essentially apply the same idea as Terraform to infrastructure to the process of creating diagrams. Instead of using GUI editor (~ AWS Console) you describe the intended diagram (~ infrastructure) in an open, free Domain Specific Language PlantUML (~ Terraform) and use free, opensource and readily available tools to transform the DSL to target assets - images (~ resources). This is the approach using PlantUML\nPlantUML diagrams # The PlantUML is well established DSL with great ecosystem and support. It allows creating wide variety of diagrams and converting them either online or in Docker or using plugin for IDE\nThere is also standard library of modules including AWS and excellent guide with examples and details\nHere is a quick demo of few examples what can be done with PlatUML\nAWS with PlantUML # @startuml !include \u0026lt;awslib/AWSCommon\u0026gt; !include \u0026lt;awslib/AWSSimplified.puml\u0026gt; !include \u0026lt;awslib/Compute/all.puml\u0026gt; !include \u0026lt;awslib/mobile/all.puml\u0026gt; !include \u0026lt;awslib/general/all.puml\u0026gt; !include \u0026lt;awslib/GroupIcons/all.puml\u0026gt; skinparam linetype polyline \u0026#39; skinparam linetype ortho package \u0026#34;AWS Cloud\u0026#34; { EC2(Smadex, \u0026#34;Smadex Service\u0026#34;, \u0026#34; \u0026#34;) } Users(Users, \u0026#34;Users\u0026#34;, \u0026#34; \u0026#34;) TraditionalServer(AdExchange, \u0026#34;Ad Exchange\u0026#34;, \u0026#34; \u0026#34;) Mobile(Mobile, \u0026#34;Publisher app or web\u0026#34;, \u0026#34; \u0026#34;) Users -down-\u0026gt; Mobile: 1. Visits Mobile -right-\u0026gt; AdExchange: 2. Start auction AdExchange -right-\u0026gt; Smadex: 3. Bid request / response Smadex -left-\u0026gt; Mobile: 4. Show Ad Users -right-\u0026gt; Smadex: 5. Impression / click / install / event {request id} @enduml @startuml !include \u0026lt;awslib/AWSCommon\u0026gt; !include \u0026lt;awslib/AWSSimplified.puml\u0026gt; !include \u0026lt;awslib/Compute/all.puml\u0026gt; !include \u0026lt;awslib/mobile/all.puml\u0026gt; !include \u0026lt;awslib/general/all.puml\u0026gt; !include \u0026lt;awslib/GroupIcons/all.puml\u0026gt; !include \u0026lt;awslib/Storage/all.puml\u0026gt; !include \u0026lt;awslib/ManagementAndGovernance/all.puml\u0026gt; !include \u0026lt;awslib/CustomerEngagement/all.puml\u0026gt; !include \u0026lt;awslib/MachineLearning/all.puml\u0026gt; !include \u0026lt;awslib/NetworkingAndContentDelivery/all.puml\u0026gt; !include \u0026lt;awslib/Database/all.puml\u0026gt; !include \u0026lt;awslib/ApplicationIntegration/all.puml\u0026gt; \u0026#39;Compute/General \u0026#39;Storage/SimpleStorageServiceS3.png \u0026#39;ApplicationIntegration/SQS.png \u0026#39;Compute/Lambda.png \u0026#39;Compute/EC2 \u0026#39;ManagementAndGovernance/CloudWatch.png \u0026#39;CustomerEngagement/SESEmail.png \u0026#39;MachineLearning/SageMaker.png \u0026#39;\u0026#39;Mobile/APIGateway.png \u0026#39;NetworkingAndContentDelivery/APIGateway2.png \u0026#39;Database/Aurora.png \u0026#39;ApplicationIntegration/SQSQueue.png skinparam linetype polyline \u0026#39; skinparam linetype ortho \u0026#39;top left section \u0026#39;------------------------------------------------------------- package EC2_Instance { General(IngestionApp, \u0026#34;Ingestion App\u0026#34;, \u0026#34; \u0026#34;) General(ChunkingApp, \u0026#34;Chunking Orchestration App\u0026#34;, \u0026#34; \u0026#34;) } SimpleStorageServiceS3(S3Staging, \u0026#34;Amazon S3 Staging Bucket\u0026#34;, \u0026#34; \u0026#34;) SQS(SQSIngest, \u0026#34;Amazon SQS Ingest Queue\u0026#34;, \u0026#34; \u0026#34;) Lambda(LambdaTrigger, \u0026#34;AWS Lambda Trigger Function\u0026#34;, \u0026#34; \u0026#34;) LambdaTrigger -up-\u0026gt; IngestionApp IngestionApp -up-\u0026gt; SQSIngest SQSIngest -down-\u0026gt; ChunkingApp S3Staging \u0026lt;-down-\u0026gt; EC2_Instance \u0026#39;top right section \u0026#39;------------------------------------------------------------- together { SQS(SQSLargeFileQueue, \u0026#34;Amazon SQS Large File Queue\u0026#34;, \u0026#34; \u0026#34;) SQS(SQSSmallFileQueue, \u0026#34;Amazon SQS Small File Queue\u0026#34;, \u0026#34; \u0026#34;) SQS(SQSSingleFileQueue, \u0026#34;Amazon SQS Single File Queue\u0026#34;, \u0026#34; \u0026#34;) EC2(LargeFileChunkingAppEC2, \u0026#34;Large File Chunking App on EC2\u0026#34;, \u0026#34; \u0026#34;) Lambda(LambdaSmallFileChunking, \u0026#34;Small File Chunking Lambda\u0026#34;, \u0026#34; \u0026#34;) Lambda(ImageConversionLambdaFunction, \u0026#34;Image Conversion Lambda Function\u0026#34;, \u0026#34; \u0026#34;) } \u0026#39;todo dashed line boundary package DLQ { SQSQueue(DLQ1, \u0026#34;DLQ\u0026#34;, \u0026#34; \u0026#34;) SQSQueue(DLQ2, \u0026#34;DLQ\u0026#34;, \u0026#34; \u0026#34;) SQSQueue(DLQ3, \u0026#34;DLQ\u0026#34;, \u0026#34; \u0026#34;) } ChunkingApp -right-\u0026gt; SQSLargeFileQueue ChunkingApp -right-\u0026gt; SQSSmallFileQueue ChunkingApp -right-\u0026gt; SQSSingleFileQueue SQSLargeFileQueue -right-\u0026gt; LargeFileChunkingAppEC2 LargeFileChunkingAppEC2 -down-\u0026gt; SQSSmallFileQueue SQSSmallFileQueue -right-\u0026gt; LambdaSmallFileChunking LambdaSmallFileChunking -down-\u0026gt; SQSSingleFileQueue SQSSingleFileQueue -right-\u0026gt; ImageConversionLambdaFunction \u0026#39;todo dashed line SQSLargeFileQueue -down-\u0026gt; DLQ1 SQSSmallFileQueue -down-\u0026gt; DLQ2 SQSSingleFileQueue -down-\u0026gt; DLQ3 \u0026#39;bottom right section \u0026#39;------------------------------------------------------------- SimpleStorageServiceS3(S3Images, \u0026#34;Amazon S3 Images Bucket\u0026#34;, \u0026#34; \u0026#34;) EC2(EC2DLQFailsafeApp, \u0026#34;DLQ Failsafe App on EC2\u0026#34;, \u0026#34; \u0026#34;) SQS(SQSConvertedImageQueue, \u0026#34;Amazon SQS Converted Image Queue\u0026#34;, \u0026#34; \u0026#34;) Lambda(LambdaInferenceInvocation, \u0026#34;Inference Invocation Lambda Function\u0026#34;, \u0026#34; \u0026#34;) Aurora(Aurora, \u0026#34;Amazon Aurora\u0026#34;, \u0026#34; \u0026#34;) APIGateway(AmazonAPIGateway, \u0026#34;Amazon API Gateway\u0026#34;, \u0026#34;\u0026#34;) SageMaker(AmazonSageMaker, \u0026#34;Amazon SageMaker Endpoint\u0026#34;, \u0026#34;\u0026#34;) DLQ1 -down-\u0026gt; EC2DLQFailsafeApp DLQ2 -down-\u0026gt; EC2DLQFailsafeApp DLQ3 -down-\u0026gt; EC2DLQFailsafeApp EC2DLQFailsafeApp -right-\u0026gt; S3Images ImageConversionLambdaFunction -down-\u0026gt; S3Images S3Images -down-\u0026gt; SQSConvertedImageQueue SQSConvertedImageQueue -left-\u0026gt; LambdaInferenceInvocation LambdaInferenceInvocation -down-\u0026gt; Aurora LambdaInferenceInvocation \u0026lt;-left-\u0026gt; AmazonAPIGateway AmazonAPIGateway \u0026lt;-left-\u0026gt; AmazonSageMaker \u0026#39;bottom left section \u0026#39;------------------------------------------------------------- CloudWatch(CloudWatch, \u0026#34;Amazon Cloudwatch\u0026#34;, \u0026#34; \u0026#34;) SNS(SNS1, \u0026#34;Amazon SNS\u0026#34;, \u0026#34;\u0026#34;) SESEmail(SESEmail, \u0026#34;Email Notification\u0026#34;, \u0026#34;\u0026#34;) CloudWatch -right-\u0026gt; DLQ CloudWatch -left-\u0026gt; SNS1 SNS1 -left-\u0026gt; SESEmail footer %filename() rendered with PlantUML version %version()\\nThe Hitchhiker’s Guide to PlantUML @enduml ( or see the source: ) - source PUML Workflow with PlantUML # Using PlantUML for diagrams is pretty straightforward. Assuming that you have installed plugin simply add the file with PUML extension to the project. It will be recognized and PyCharm/IntelliJ will show colored syntax with preview:\nAfter creating the desired image, use the plugin save button to generate PNG version of the diagram and add it to the project - ideally same folder as the PUML file.\nIncluding the sources into documentation is very simple: you can either embedd the full source or provide link to it\nPure Python as graph DSL # Recently I have discovered different approach to specifying diagrams in a source code friendly manner. There is an open source project diagrams - see also github. Good introduction to this approach is this blog.\nIt is elegant and beautiful.\nFrom this: generates this\n","date":"August 10, 2020","externalUrl":null,"permalink":"/posts/2020-08-07-architecture-as-a-code/","section":"Posts","summary":"Many shapes of Architecture # According to the wise people, an architecture is the shared understanding that the expert developers/system builders/maintainers have of the system design. It’s purpose is to maximize the probability that the decisions you have to make early in a project are the right ones. It is sort of a blueprint for the future system and captures parts, relations, boundaries, constraints.\n","title":"Reference Architecture as a Code","type":"post"},{"content":"","date":"August 10, 2020","externalUrl":null,"permalink":"/tags/terraform/","section":"Tags","summary":"","title":"Terraform","type":"tags"},{"content":"","date":"May 30, 2020","externalUrl":null,"permalink":"/tags/docker/","section":"Tags","summary":"","title":"Docker","type":"tags"},{"content":"I had an opportunity to attend DockerCon 2018 in person - it was great experience in wonderful city - Barcelona. My notes from it are here. I missed previous year (for variety of reasons), but DockerCon this year (as many other tech events) was purely virtual so I was able to see some part of it.\nCompared to 2018, the general tone and content of this DockerCon was quite different. In 2018 it felt like all the attention is focused on big enterprise (mainly Microsoft related) and what Docker as a company is looking for best way how to hook big firms with deep pockets.\nDockerCon 2020 Live felt different - not only because it was online event, without booths, party, workshops and crowds. I had the impression that Docker is focusing once again on developers and I did not miss the enterprisey flavour at all.\nHere are few of the interesting presentations - full agenda is at here\nThe First 10M Pulls: Building the official Curl Image for Docker Hub # by James Fuller: https://docker.events.cube365.net/docker/dockercon/content/Videos/yKyKXvufcho7ZyE4E\nInteresting background information on workflow and lesson learned while maintaining official docker image for one of the most used tools for accessing http endpoints.\nDid you know that curl has around 10 billion deployment ? I did not, neither did I know of curl-configure command. Man lernt nie aus.\nAdditional links:\nhttps://github.com/curl/curl-docker https://curl.haxx.se/book.html https://ec.haxx.se/ Multi container application with Nginx, React, Node and Mongo DB # by Lukonde Mwila: https://docker.events.cube365.net/docker/dockercon/content/Videos/NNkrWWqJSgBBy3nf3\nWalkthrough through dockerizing React app consisting of multiple containers, using docker compose to run it and deploy it AWS using Beanstalk.\nSee https://github.com/LukeMwila/multi-container-nginx-react-node-mongo for the code.\nBest Practices for Compose-managed Python Applications # by Anca Lordache: https://docker.events.cube365.net/docker/dockercon/content/Videos/eWWPtj5dmHAmoYypc\nThis talk focuses on best practices for Python projects with Docker Compose, how to bootstrap a project and an example development workflow with debugging and automated testing\nSee also https://github.com/aiordache/demos and (unrelated to DockerCon but related to the topic) https://www.youtube.com/watch?v=w6TVyxNpJ80\u0026feature=youtu.be\nAlso, worth looking at is Awesome Docker Compose samples repo\nBecome a Docker Power User With Microsoft Visual Studio Code # by Brian Christner - https://docker.events.cube365.net/docker/dockercon/content/Videos/4YkHYPnoQshkmnc26\nEye opening demo of Visual Studio plugins for Docker. Also see Brian\u0026rsquo;s Github\nBuilding a Docker Image Packaging Pipeline Using GitHub Actions # by Gareth Rushgrove - https://docker.events.cube365.net/docker/dockercon/content/Videos/SPWM3BdnCZWPN4fN9\ndiscusses techniques for building reusable Dockerfiles, difference between packaging from source and packaging from artefacts with advanced use cases, demonstrating the powerful combination of build arguments, multi-stage Dockerfiles and BuildKit\nSee also Gareth\u0026rsquo;s Github, article on multistage build patterns and Snyk\nPeeking Inside Your Containers and Infrastructure # by Mike Elsmor - https://docker.events.cube365.net/docker/dockercon/content/Videos/SNLT7AEW5e32cTpY2\nTalk about observability of the infrastructure and the applications using open source tools. Also, worth checking is author\u0026rsquo;s Github and product\nAccess Logging Made Easy With Envoy and Fluent Bit # by Carmen Puccio (despite the nice spainitalian flare of the name, he is a guy) - https://docker.events.cube365.net/docker/dockercon/content/Videos/t2ykDpEams3GDwbYy.\nSession about how to implement a consistent and structured log format for microservices applications with Envoy and Fluent Bit.\n","date":"May 30, 2020","externalUrl":null,"permalink":"/posts/2020-05-30-dockercon-2020/","section":"Posts","summary":"I had an opportunity to attend DockerCon 2018 in person - it was great experience in wonderful city - Barcelona. My notes from it are here. I missed previous year (for variety of reasons), but DockerCon this year (as many other tech events) was purely virtual so I was able to see some part of it.\nCompared to 2018, the general tone and content of this DockerCon was quite different. In 2018 it felt like all the attention is focused on big enterprise (mainly Microsoft related) and what Docker as a company is looking for best way how to hook big firms with deep pockets.\n","title":"DockerCon 2020","type":"post"},{"content":"","date":"May 30, 2020","externalUrl":null,"permalink":"/categories/events/","section":"Categories","summary":"","title":"Events","type":"categories"},{"content":"First step is to get your personal token. Log on to Terraform Cloud, go to https://app.terraform.io/app/settings/tokens and generate new token.\nNote: it is important to save the token to safe place - this is only time you will see it.\nExport the token:\nexport TFE_TOKEN=\u0026lt;THE-TOKEN-VALUE\u0026gt; The documentation for Terraform API is here\nIt is OK documentation but not the greatest one, however. There are two versions of the API - v1 and v2 and this is not clearly described. It could also used better examples.\nHere is some useful information one can do with the freshly acquired token:\n# Get the account info curl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/v2/account/details | jq . { \u0026#34;data\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;user-\u0026lt;DELETED\u0026gt;7\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;users\u0026#34;, \u0026#34;attributes\u0026#34;: { \u0026#34;username\u0026#34;: \u0026#34;\u0026lt;DELETED\u0026gt;\u0026#34;, \u0026#34;is-service-account\u0026#34;: false, \u0026#34;avatar-url\u0026#34;: \u0026#34;https://www.gravatar.com/avatar/db6b71\u0026lt;DELETED\u0026gt;?s=100\u0026amp;d=mm\u0026#34;, \u0026#34;password\u0026#34;: null, \u0026#34;enterprise-support\u0026#34;: true, \u0026#34;is-site-admin\u0026#34;: false, \u0026#34;is-sso-login\u0026#34;: false, \u0026#34;two-factor\u0026#34;: { \u0026#34;enabled\u0026#34;: true, \u0026#34;verified\u0026#34;: true }, \u0026#34;email\u0026#34;: \u0026#34;\u0026lt;DELETED\u0026gt;\u0026#34;, \u0026#34;unconfirmed-email\u0026#34;: null, \u0026#34;has-git-hub-app-token\u0026#34;: false, \u0026#34;is-confirmed\u0026#34;: true, \u0026#34;onboarding-status\u0026#34;: null, \u0026#34;permissions\u0026#34;: { \u0026lt;DELETED\u0026gt; } }, \u0026#34;relationships\u0026#34;: { \u0026#34;authentication-tokens\u0026#34;: { \u0026#34;links\u0026#34;: { \u0026#34;related\u0026#34;: \u0026#34;/api/v2/users/user-\u0026lt;DELETED\u0026gt;/authentication-tokens\u0026#34; } } }, \u0026#34;links\u0026#34;: { \u0026#34;self\u0026#34;: \u0026#34;/api/v2/users/user-\u0026lt;DELETED\u0026gt;\u0026#34; } } } export MY_ORG=\u0026lt;YOUR-ORG-IN-TERRAFORM-CLOUD-NAME\u0026gt; # Get the teams for the organization curl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/v2/organizations/$MY_ORG/teams | jq . curl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/v2/organizations/$MY_ORG/workspaces | jq . In order to list modules (my original intent), one must use V1 of the API:\ncurl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/registry/v1/modules | jq . { \u0026#34;meta\u0026#34;: { \u0026#34;limit\u0026#34;: 15, \u0026#34;current_offset\u0026#34;: 0, \u0026#34;next_offset\u0026#34;: 15, \u0026#34;next_url\u0026#34;: \u0026#34;//@/v1/modules?namespace=\u0026lt;DELETED\u0026gt;\u0026#34; }, \u0026#34;modules\u0026#34;: [ { \u0026#34;id\u0026#34;: \u0026#34;\u0026lt;DELETED/iam-role/aws/0.5.1\u0026#34;, \u0026#34;owner\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;namespace\u0026#34;: \u0026#34;\u0026lt;DELETED\u0026gt;\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;iam-role\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.5.1\u0026#34;, \u0026#34;provider\u0026#34;: \u0026#34;aws\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Terraform Module - AWS IAM Role\u0026#34;, \u0026#34;source\u0026#34;: \u0026#34;https://github.com/\u0026lt;DELETED\u0026gt;\u0026#34;, \u0026#34;tag\u0026#34;: \u0026#34;\u0026#34;, \u0026#34;published_at\u0026#34;: \u0026#34;2020-04-18T13:53:47.261884Z\u0026#34;, \u0026#34;downloads\u0026#34;: 1345, \u0026#34;verified\u0026#34;: false }, \u0026lt;DELETED\u0026gt; ] } In order to retrieve more than 15 , use the limit URL parameter:\ncurl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/registry/v1/modules\\?limit\\=100 Here is example that lists only the names of the modules in the repository.\ncurl -s --header \u0026#34;Authorization: Bearer $TFE_TOKEN\u0026#34; --request GET https://app.terraform.io/api/registry/v1/modules\\?limit\\=100 | jq \u0026#39;.modules[].id\u0026#39; | sort ","date":"May 14, 2020","externalUrl":null,"permalink":"/posts/2020-05-14-accessing-tfcloud-api/","section":"Posts","summary":"First step is to get your personal token. Log on to Terraform Cloud, go to https://app.terraform.io/app/settings/tokens and generate new token.\nNote: it is important to save the token to safe place - this is only time you will see it.\nExport the token:\nexport TFE_TOKEN=\u003cTHE-TOKEN-VALUE\u003e The documentation for Terraform API is here\nIt is OK documentation but not the greatest one, however. There are two versions of the API - v1 and v2 and this is not clearly described. It could also used better examples.\n","title":"Accessing Terraform cloud Module registry programatically","type":"post"},{"content":"","date":"May 14, 2020","externalUrl":null,"permalink":"/tags/cli/","section":"Tags","summary":"","title":"Cli","type":"tags"},{"content":"","date":"May 12, 2020","externalUrl":null,"permalink":"/tags/ssh/","section":"Tags","summary":"","title":"Ssh","type":"tags"},{"content":"I have been using Bitbucket since 2012, long before my company moved from in-house hosted server running Gitolite and in-house instances of FishEye and Crucible to cloud based source control on Bitbucket Cloud. As legacy I was using my personal login with my gmail account as my Bitbucket identity.\nWith merge of 3 companies in 2018 and rebranding as Pivotree, we are in process of streamlining the identity management and using SSO for identification. Time has come to split my personal identity and work identity.\nI have created second Bitbucket account with work email and added \u0026lsquo;-pvt\u0026rsquo; to my login to keep them separate, removed the old myself from work worspaces and added the new myself instead. So far so good. The problems started when I wanted to keep using git based urls and needed new keypair. One cannot register same public key with two different Bitbucket accounts, so I needed new key:\nssh-keygen -f ~/.ssh/bitbucket-pivotree but cloning did not work (for repository visible in Web UI):\ngit clone -v git@bitbucket.org:thinkwrap/tw-bitbucket-admin.git Cloning into \u0026#39;tw-bitbucket-admin\u0026#39;... Forbidden fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. An attempt to add key to ssh daemon ssh-add ~/.ssh/bitbucket-pivotree did not solve the problem either.\nSolution # I had to define explicitly two different URLs for bitbucket in ~/.ssh/config file:\nHost work.bitbucket.org HostName bitbucket.org User git IdentityFile ~/.ssh/bitbucket-pivotree Host bitbucket.org HostName bitbucket.org User git IdentityFile ~/.ssh/id_rsa Now for cloning work repositories, I can use the\ngit clone -v git@work.itbucket.org:thinkwrap/tw-bitbucket-admin.git and the work key will be automatically used.\nFor existing - already cloned repos, here is simple way how to reset the remote URL:\ngit remote set-url origin $(git remote -v | grep fetch | awk \u0026#39;{print $2;}\u0026#39; | sed \u0026#39;s/git@bit/git@work.bit/\u0026#39;) ","date":"May 12, 2020","externalUrl":null,"permalink":"/posts/2020-05-12-bitbucket-keys/","section":"Posts","summary":"I have been using Bitbucket since 2012, long before my company moved from in-house hosted server running Gitolite and in-house instances of FishEye and Crucible to cloud based source control on Bitbucket Cloud. As legacy I was using my personal login with my gmail account as my Bitbucket identity.\nWith merge of 3 companies in 2018 and rebranding as Pivotree, we are in process of streamlining the identity management and using SSO for identification. Time has come to split my personal identity and work identity.\n","title":"Using SSH keys with multiple Bitbucket accounts","type":"post"},{"content":"","date":"March 31, 2020","externalUrl":null,"permalink":"/tags/cloud/","section":"Tags","summary":"","title":"Cloud","type":"tags"},{"content":" The beginnings # Once upon a time - actually, in late 2017-early 2018 - there was a QA/DevOps engineer named José who liked containers, Docker and worked for a company named Thinkwrap (that soon would become Pivotree) in Valencia, Spain.\nJosé was responsible (among other things) for setting up integration and QA environments for multiple Hybris projects. Such environment, when being built in traditional way (from physical servers or VMs), normally requires quite a few pieces:\nat least one front-end server, running Web layer (Nginx or Apache or both) one or more application servers, running Tomcat with Hybris application usually one dedicated backend server, used for catalog management, cron jobs and other backoffice activities Solr server or cluster for search functionality (typically working in master slave setup in production) Jenkins server to run and administer pipelines that executed unit tests and integration tests Sonarqube server that provided code quality tools (internally consisting of Java based server and a database - usually PostgreSQL) Setting up and maintaining this cuckoo-clock of servers and services and especially running multiple environments without going overboard with server management overhead was definitely not easy. It would take 1-2 days setting up such an environment from scratch (meaning start with OS). Just a single one environment \u0026hellip;\nJosé did not have that amount of time and did not particularly like doing the same steps over and over. He also could not guarantee he would not never make a mistake or leave out and would not have to start over. In accordance with 3 virtues of Great Programmers (see http://threevirtues.com/), José decided to package and automate the hell out of that.\nThinkwrap Valencia office had good experience with using containers so José started there: using existing public images for Jenkins, Sonar, Solr, Nginx and database and Thinkwrap custom-built images for Hybris app servers he quickly managed to build working docker-compose setup that allowed him (and any developer brave enough to run Docker on her Mac) to spin up the multitude of containers that encapsulated all apps and configurations for the environment.\nYes, Macbooks are powerful beasts, but even on Quad-core i7 with 16 GB RAM the environment cannot run 6-7 docker images easily, when one or two of them are 6 GB monster Hybris containers. Other applications that are memory hogs (yes, I am looking at you - Chrome, Slack, Visual Studio Code and IntelliJ) will become annoyingly slow and using this environment will eventually become an exercise of patience. And do not even think of running two copies of the environment \u0026hellip;\nSo José started to search for a server. There is this place called AWS that has plenty of servers, but there is a small problem with them: they cost money. Unfortunately, most clients are rather unfriendly when asked for additional monthly funds to run something businesswise unimportant such as unit tests and code quality tools. As a consequence, most PMs were not brave enough to raise that topic with clients, so José had to look elsewhere.\nAs it happened, the partner company Tenzing (that was in process of acquiring Thinkwrap at that time) was a hosting company and had some free capacity in the datacenter. Friendly techie from Tenzing installed Openstack or rather generous hardware allocation: 400 GB of RAM, loooots of disk space and carved out 5 VMs with memory ranging from 128GB of RAM to 16 GB of RAM. José named them: Faith, Raiden, Deku, Quiet and yScout. The names may have something to do with comic books - ask younger people that are knowledgeable of geek culture of the late 90-ies. I am personally more like Hacker\u0026rsquo;s Dictionary generation - https://en.wikipedia.org/wiki/Jargon_File\nAnd this is how a server named Faith was born - an Ubuntu VM 128 GB or RAM and ~ 200 GB of disk space.\nAnyway, back to José and his problem. In addition to Docker, he was also intrigued with Kubernetes, and saw clearly how the declarative nature, namespaces and explicit constructs for Config and Secrets would help him. Thinkwrap at that time had already built 2 or 3 Kubernetes clusters in AWS for microservices projects related to eCommerce. These were however built using a tool called Kops (please remember this was before EKS became generally available) which was just at that time, just a Cloudformation generator and thus completely unusable outside of AWS.\nFull installation of Kubernetes \u0026ldquo;the hard way\u0026rdquo; would require access to and knowledge of low level networking tools and settings. To avoid that, José searched - and found - a tool that not only would bootstrap a full Kubernetes cluster inside a single node but also give him UI to deploy and manage that non-clustery cluster: Rancher. Yes, this solution did not have ANY high availability or failover capability and pretty much everything was a single point of failure.\nThere were few more challenges José had to address: the first one was DNS. Different Hybris instances require unique URLs to resolve to the address of a container. The solution was combination of free service XIP.IO that accepts URLs in form: ANYTHING.AAA.BBB.CCC.DDD.xip.io and resolves it to IP address AAA.BBB.CCC.DDD - where AAA,BBB,CCC,DDD are decimal numbers 0-255. There was only one public IP, so every URL contained the same public IP + .xip.io and differed only in the ANYTHING portion. Beyond the public IP, there was Kubernetes Ingress that based on ANYTHING string routed the requests to proper internal service in a namespace.\nThe second challenge was the Docker-in-Docker problem with Jenkins. The Jenkins server was using pipelines that were both building Docker images as well as running them. This caused an issue when initiated from inside Docker. To solve this, a second VM (yScout) was used to operate as Jenkins slave, outside of Kubernetes cluster. The Jenkins master (inside Docker) controlled Jenkins slave - that was installed on Ubuntu - which could use and run Docker without any issues.\nThe solution worked, developers loved it - using Rancher console to access log files and to modify parameters of workloads was a piece of cake. Life was good.\nTroubles with Faith # The PS business during 2017-2018 was great, the Valencia team grew and started to work on new projects. The developers loved the easy to use toolchain behind Rancher and automation they saw in use in existing projects - and wanted the new project to have the same. Eventually Faith ran out of capacity - at first, disk space. It turned out the original guesstimates for disk capacity were way too conservative. It was not a huge technical problem to add disk space as the datacenter still had some capacity, but it did require low level changes in VM parameters which required downtime. And downtime on a shared server is a big deal. As Murphy\u0026rsquo;s law defines it took several weeks to find a window where all of the hosted projects were OK with their QA / Integration environment being down AND the scarce technical resource from Tenzing that had both the knowledge and the skills for making low level adjustments in OpenStack was available.\nMeanwhile, José submitted his resignation and left the company. He tried his best to do knowledge transfer, but when there is nobody available to replace leaving engineers right away and multiple people are expected to \u0026ldquo;temporarily\u0026rdquo; own pieces of José\u0026rsquo;s portfolio, a gap was created: there was nobody available who would own Faith\u0026rsquo;s maintenance and upkeep for all projects. With multiple projects sharing the resource and none of them actually budgeting for it, there were no volunteers to finance it either. If the Faith setup was fully scripted and automated, it would have been easier - but with everything being setup via Rancher console, one would only see the end result and troubleshooting would require first hand knowledge of everything that happened to that particular configuration. That knowledge was gone, as José was enjoying steaks in Argentina and learning Google Cloud for his new DevOps gig.\nAll summed up, we have eventually upgraded Faith and after several iterations added the new projects. But it took several weeks of going back and forth, finding out broken things and searching for solutions. This must have been annoying for all project leads, experiencing downtime and some hiccups. Some projects soon wanted to add new features (like multi-branch parallel unit testing) which pushed the need for resources and there was real danger that the whole circus would have to repeat. The Faith still did not have a new owner - despite that new DevOps guy being hired and replacing José\u0026rsquo;s work for CI/CD evolution, none of the projects had any realistic budget for infrastructure projects or resources.\nTo make things worse, the XIP.IO became flaky and unreliable and added even more interruption. People say \u0026ldquo;you get what you pay for\u0026rdquo; - so using free service ended up wasting lots of time (and money) by interruption and investigations that turned up leading nowhere as intermittent DNS failures have been causing a wide range of really interesting exceptions inside the pipelines.\nKubernetes, Rancher and Docker are very dynamic systems and since 2018 many new versions have come. We have never upgraded the Faith system though as it was near impossible to find a suitable window - and as nobody really wanted to bear the cost of this work.\nSecurity was never the most important concern for development and non-production environments - the approach features first, hardening second makes sense when the deadlines are really tight and there is a need to make the next sprint demo. Some of the tools used inside stacks in projects are rather old and have their own share security issues. As the Faith have single external public IP, we had to start whitelisting the access to K8s cluster and to all hosted projects to hide these vulnerable tools (hello Jenkins, hello Sonarqube). Adding whitelisting created lots of issues for development teams working from home and 3rd parties collaboration. And it also took forever - because the management of the firewall layer was a manual process using MS services in different timezones. Because of that, sometimes simple addition of IP or opening additional ports took several iterations and sometimes days for something that is a matter of minutes if the system was hosted in an AWS VPC.\nAs of now (March 2020), all the projects that were added to Faith are still there (as long as they are active). Everything kinda works - for now - provided that XIP.IO is having a good day. There is still just a single cluster with a single Jenkins slave host - two big single points of failure.\nLessons Learned # There is a proverb about road to hell and good intentions, which is very much applicable in this case. Nobody did really anything wrong in the case of Faith, most decisions were best shots of all participants to solve urgent problems with available tools, taking immediate needs into account and spending as little time and dollars as possible. This series of seemingly correct tactical decisions created a big ball of technical debt that is now preventing progress and slowing us down.\nWith a hindsight, here is what we should have done differently:\nWe should have chosen AWS, not datacenter. This would have eliminated capacity problem and scaling, would allow to decide whether to add more servers when needed or even create duplicate of the setup if required.\nInstead of taking provisioned servers and manually configuring them via Rancher console, we should have used automated tools “Infrastructure as a Code” such as CloudFormation or Terraform to create everything - so that the script would not only be source of all configuration, it would allow recreate it or create more copies. Note the #2 is possible only as consequence of #1 - the use of automation and IaaC inside the data center is quite limited.\nInstead of combining projects, we should have gone with per project infrastructure, which would have simplified ownership issues from business point of view as well as eliminate single point of failure and downtime windows issue.\nWe should have avoided using free services (hello XIP.IO) and go with standard DNS, together with AWS network infrastructure. This would have allowed manage security efficiently on per project basis and freely cooperate with 3rd parties, while properly isolating both customers and development teams.\nWe should have considered self service by developers as one the most important features and avoid any workflows that would depend on specialized third party access or knowledge.\nThe psychological aspect of using or not using automation is also very important. If one puts lots of effort, sweat and time into configuring a server manually, he or she will be very hesitant to throw it away and will hang on to it. The answer to a question “the project goes on pause for next 2-3 weeks, could we shut the QA / Integration down to save some cost” will be clear and sound “Hell, NO !”. Not only because nobody remembers EXACTLY those little tweaks and fixes that were applied over weeks to get system to state where it is now, but also because everybody remembers very well the long hours spent to get it set up in the first place. This is well known as Escalation of Commitment - see https://en.wikipedia.org/wiki/Escalation_of_commitment. As a result, the once created servers are rarely touched or replaced voluntarily and let to slowly rot up to the point where external events like hardware failure will make everybody face a new reality they cannot change. Then the panic begins and another quick tactical decision is made to get things up and running ASAP, increasing the technical debt even more.\nThe key factor here is that properly automating something versus using some console or GUI to manually set it up always takes longer (usually several times longer) - just compare clicking away to get some AWS servers deployed vs. writing a proper Terraform script wrapped in a pipeline. If all you need is this ONE system and you completely ignore all the other factors - scalability, auditability, maintainability, extensibility, documentation, knowledge retention, it may even be a good approach.\nThis shortsightedness is the main cause of all duck-taped frankenservers I have seen out there. Just a quick fix,let’s put in a temporary solution when we will have more time and be out of time crunch. We will come back and fix it later. In 99% of the cases, LATER equ NEVER.\nSolution =\u0026gt; OneClick # We have been working since few weeks on different approach, with working name \u0026ldquo;OneClick Development Environment\u0026rdquo;\nThe main objective is fully automated, GitOps inspired system that is able to create fully functioning Dev QA environment for Hybris (at first) but eventually any templatized project from scratch within 2 hours, including full infrastructure setup, QA tools, CI/CD pipeline and deployment of a functioning app.\nWith all the above mentioned history, automation will be the king. Apologies to you - cash - in this case you have to be dethroned. Automation dictates it must be IaaC based solution. The fact that we are living in 2020 dictates it needs to be cloud-native. Putting these together, results in an on-demand, create anytime, destroy anytime, pay-as-you go solution.\nWe use EKS “bootstrap” install for small footprint K8s clusters to keep costs down. Terraform state is hosted inside the AWS account (S3 + DynamoDB) to separate the DEV/QA world from production systems using the Terraform Enterprise backend. This way, there is no need to manually setup the accounts and we can keep dev teams out of production infrastructure territory.\nEverything is pipeline driven - so no tooling on the developer\u0026rsquo;s machine required.\nDeveloper uses the provided CLI tool to create project specific forks the infrastructure repo and an app template repo and adds values for variables. We assume that each project will have separate DEV AWS account created and team lead will enter the provided credentials to variables of the Bitbucket pipeline\nThe infrastructure pipelines creates full infrastructure, including all code quality tools and Jenkins installation, specific for a project. Everything is fully configured and available within ~ 20 minutes after the pipeline run. Instead of co-locating multiple projects, we host all Dev/QA environments for a single project in one cluster. This allows running multiple versions of an application in different namespaces of the cluster - multibranch development and testing.\nThe application repository inherits all automation components from the app template. While the application contains the actual project specific code, the inherited pieces (detailed specification of the project build and deployment pipelines) are customized versions of the template shared within a group of projects - e.g. Hybris project app template.\nThe important prerequisite for this to happen is the “pre-containerization” of the project. The application template must contain Dockerfile for building images for all components of the running application and a Helm chart that defines topology and allow to run this application inside a Kubernetes cluster. This may represent significant effort for some classes of applications, however - with current trends seen in enterprise applications, everything is moving to containers in the cloud so having this ability is essential for the future anyway.\nBenefits of the new solution # Using infrastructure designed according to the principles stated above, maximizes the “on-demand-ness” - so that we can schedule shutdown of environments for 10/hrs a day and weekends and any developer with access to Bitbucket repo can bring it up if required. We can have as many environments as we need, with very short start time (\u0026lt; 2hrs) from zero, without any issues of clinging to and taking care of something that was very hard to get.\nEven with overhead of per-project infrastructure, it may be the end cheaper than a shared large cluster running 24x7x365 because multiple projects depend on it.\nIt is much easier to keep the system up to date. Instead of maintenance or patching, we can simply use the latest version of images for tools such as Jenkins, Sonar and every new environment will automatically use them. To update an existing environment, we simply rebuild it - this is probably faster than patching and leads to better defined outcome.\nBy delegating the operation to developers via pipelines, we can eliminate the need for maintenance of these environments. All the beforehand had to be done by specialized resources, is now packaged and available to the development team - creation, configuration and whitelisting for remote access. And by using dedicated cloud accounts, there is no increased risk of allowing non-production teams accessing and modifying network resources that are shared between non-production and production accounts.\nBy using templates based infrastructure and project repositories, we are closer to unified structure of projects and have increased the reuse of the most recipes/scripts. This leads to less code, and ultimately to less maintenance.\nLife is good, again :-)\n","date":"March 31, 2020","externalUrl":null,"permalink":"/posts/2020-03-31-history-of-faith/","section":"Posts","summary":"The beginnings # Once upon a time - actually, in late 2017-early 2018 - there was a QA/DevOps engineer named José who liked containers, Docker and worked for a company named Thinkwrap (that soon would become Pivotree) in Valencia, Spain.\nJosé was responsible (among other things) for setting up integration and QA environments for multiple Hybris projects. Such environment, when being built in traditional way (from physical servers or VMs), normally requires quite a few pieces:\n","title":"History of Faith","type":"post"},{"content":"","date":"March 31, 2020","externalUrl":null,"permalink":"/tags/k8s/","section":"Tags","summary":"","title":"K8s","type":"tags"},{"content":"","date":"March 31, 2020","externalUrl":null,"permalink":"/tags/kubernetes/","section":"Tags","summary":"","title":"Kubernetes","type":"tags"},{"content":"","date":"March 31, 2020","externalUrl":null,"permalink":"/categories/startup-life/","section":"Categories","summary":"","title":"Startup-Life","type":"categories"},{"content":"","date":"January 19, 2020","externalUrl":null,"permalink":"/tags/kubectl/","section":"Tags","summary":"","title":"Kubectl","type":"tags"},{"content":" Accessing Rancher cluster # I was doing update on Kubernetes cluster I had not touch in a while when I noticed weird behaviour:\nthe output of get command was incomplete the -o wide option had no effect on the command output (IP addresses are masked)\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get nodes NAME AGE ip-172-xx-xx-xx.ca-central-1.compute.internal 613d ip-172-xx-xx-xx.ca-central-1.compute.internal 628d ip-172-xx-xx-xx.ca-central-1.compute.internal 558d and\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get nodes -o wide NAME AGE ip-172-xx-xx-xx.ca-central-1.compute.internal 613d ip-172-xx-xx-xx.ca-central-1.compute.internal 628d ip-172-xx-xx-xx.ca-central-1.compute.internal 558d Same behaviour can be seen for pods, svc etc\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get pods | head -2 NAME AGE admin-deployment-c47f669fb-cnf2d 95d ➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get pods -o wide | head -2 NAME AGE admin-deployment-c47f669fb-cnf2d 95d ➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get svc | head -2 NAME AGE admin 503d ➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get svc -o wide | head -2 NAME AGE admin 503d ➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get deploy -o wide | head -2 NAME AGE admin-deployment 503d However, the -o yaml format works\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get pods -o yaml | head -10 apiVersion: v1 items: - apiVersion: v1 kind: Pod metadata: annotations: deploymentDate: 2018-11-08T12:56:27+0000 kubernetes.io/limit-ranger: \u0026#39;LimitRanger plugin set: cpu request for container admin\u0026#39; creationTimestamp: \u0026#34;2019-10-12T01:30:33Z\u0026#34; .... .... Root cause and solution # The cluster was built in 2018 using kops and has not been upgraded since.\nWhile we were working on other projects, the my local kubectl was upgraded few times and and currently the client is newer than server.\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat version Client Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;16\u0026#34;, GitVersion:\u0026#34;v1.16.3\u0026#34;, GitCommit:\u0026#34;b3cbbae08ec52a7fc73d334838e18d17e8512749\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2019-11-14T04:24:34Z\u0026#34;, GoVersion:\u0026#34;go1.12.13\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;darwin/amd64\u0026#34;} Server Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;9\u0026#34;, GitVersion:\u0026#34;v1.9.3\u0026#34;, GitCommit:\u0026#34;d2835416544f298c919e2ead3be3d0864b52323b\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2018-02-07T11:55:20Z\u0026#34;, GoVersion:\u0026#34;go1.9.2\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;linux/amd64\u0026#34;} The newer version of client does not seem to work with older server version - it would look like regression testing was not 100% complete.\nI started to install older versions of the clients, going backwards.\nThe version 1.11.7 from January 2019 works OK\nVER=v1.11.7 curl -LO \u0026lt;https://storage.googleapis.com/kubernetes-release/release/${VER}/bin/darwin/amd64/kubectl\u0026gt; mv kubectl kubectl1117 chmod +x kubectl1117 ➜ .kube git:(master) ✗ ./kubectl1117 --kubeconfig dropship-dev-uat version Client Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;11\u0026#34;, GitVersion:\u0026#34;v1.11.7\u0026#34;, GitCommit:\u0026#34;65ecaf0671341311ce6aea0edab46ee69f65d59e\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2019-01-24T19:32:00Z\u0026#34;, GoVersion:\u0026#34;go1.10.7\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;darwin/amd64\u0026#34;} Server Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;9\u0026#34;, GitVersion:\u0026#34;v1.9.3\u0026#34;, GitCommit:\u0026#34;d2835416544f298c919e2ead3be3d0864b52323b\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2018-02-07T11:55:20Z\u0026#34;, GoVersion:\u0026#34;go1.9.2\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;linux/amd64\u0026#34;} ➜ .kube git:(master) ✗ ./kubectl1117 --kubeconfig dropship-dev-uat get nodes NAME STATUS ROLES AGE VERSION ip-172-xx-xx-xx.ca-central-1.compute.internal Ready node 1y v1.9.3 ip-172-xx-xx-xx.ca-central-1.compute.internal Ready master 1y v1.9.3 ip-172-xx-xx-xx.ca-central-1.compute.internal Ready node 1y v1.9.3 # IP\u0026#39;s masked ➜ .kube git:(master) ✗ ./kubectl1117 --kubeconfig dropship-dev-uat get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-172-xx-xx-xx.ca-central-1.compute.internal Ready node 1y v1.9.3 172.xx.xx.xx 35.xx.xx.171 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-xx-xx-xx.ca-central-1.compute.internal Ready master 1y v1.9.3 172.xx.xx.xx 35.xx.xx.175 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-xx-xx-xx.ca-central-1.compute.internal Ready node 1y v1.9.3 172.xx.xx.xx 52.xx.xx.218 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ➜ .kube git:(master) ✗ ./kubectl1117 --kubeconfig dropship-dev-uat get pods | head -3 NAME READY STATUS RESTARTS AGE admin-deployment-c47f669fb-cnf2d 1/1 Running 0 95d admin-deployment-c47f669fb-qtldc 1/1 Running 0 95d ➜ .kube git:(master) ✗ ./kubectl1117 --kubeconfig dropship-dev-uat get pods -o wide | head -3 NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE admin-deployment-c47f669fb-cnf2d 1/1 Running 0 95d 100.xx.xx.xx ip-172-xx-xx-xx.ca-central-1.compute.internal \u0026lt;none\u0026gt; admin-deployment-c47f669fb-qtldc 1/1 Running 0 95d 100.xx.xx.xx ip-172-xx-xx-xx.ca-central-1.compute.internal \u0026lt;none\u0026gt; The alternative solution (better one) would be upgrading the cluster to latest version of Kubernetes. However, this is much more time consuming and it would require to bring all clusters to same version - DEV, UAT and PROD and would require thorough testing. This quick workaround allowed us to move ahead.\nWritting it down in case somebody else has same issue.\n","date":"January 19, 2020","externalUrl":null,"permalink":"/posts/2020-01-19-kubectl-version/","section":"Posts","summary":"Accessing Rancher cluster # I was doing update on Kubernetes cluster I had not touch in a while when I noticed weird behaviour:\nthe output of get command was incomplete the -o wide option had no effect on the command output (IP addresses are masked)\n➜ .kube git:(master) ✗ kubectl --kubeconfig dropship-dev-uat get nodes NAME AGE ip-172-xx-xx-xx.ca-central-1.compute.internal 613d ip-172-xx-xx-xx.ca-central-1.compute.internal 628d ip-172-xx-xx-xx.ca-central-1.compute.internal 558d and\n","title":"Kubectl client and server version mismatch","type":"post"},{"content":"","date":"January 18, 2020","externalUrl":null,"permalink":"/tags/rancher/","section":"Tags","summary":"","title":"Rancher","type":"tags"},{"content":" Accessing Rancher cluster # After creation, you can access the K8s cluster running Rancher by saving the config file available from the console and using standard kubectl command\nkubectl --kubeconfig ./quickstart.kubeconfig get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-5c98cb979f-bbhxf 1/1 Running 0 5d23h cattle-system cattle-node-agent-dwnxk 1/1 Running 0 5d23h cattle-system kube-api-auth-d4zgq 1/1 Running 0 5d23h ingress-nginx default-http-backend-67cf578fc4-grmsw 1/1 Running 0 5d23h ingress-nginx nginx-ingress-controller-mpnmb 1/1 Running 0 5d23h kube-system canal-jw85q 2/2 Running 0 5d23h kube-system coredns-5c59fd465f-47q5z 1/1 Running 0 5d23h kube-system coredns-autoscaler-d765c8497-sm5xf 1/1 Running 0 5d23h kube-system metrics-server-64f6dffb84-bp864 1/1 Running 0 5d23h kube-system rke-coredns-addon-deploy-job-95qnk 0/1 Completed 0 5d23h kube-system rke-ingress-controller-deploy-job-brv7w 0/1 Completed 0 5d23h kube-system rke-metrics-addon-deploy-job-tvt89 0/1 Completed 0 5d23h kube-system rke-network-plugin-deploy-job-7rqcr 0/1 Completed 0 5d23h The same information (and much more) is available using rancher CLI.\nUsing Rancher CLI # After downloading and installing Rancher CLI (see https://rancher.com/docs/rancher/v2.x/en/quick-start-guide/cli/) we need API keys to authenticate against cluster.\nThe URL is https://CLUSTER-IP/apikeys - see\nGenerate new token and make sure there is NO SCOPE selected. If you generate token scoped to cluster (it seems to be the intuitively correct choice) the token will not work and will lead to this error message:\nrancher login https://18.204.194.218/v3 --token token-jbh7m:4zrjfbzvqtq9lbtkzzw2pckfd8r6qd9542dhqwrr2nh6gjf4f6wtlw The authenticity of server \u0026#39;https://18.204.194.218\u0026#39; can\u0026#39;t be established. Cert chain is : [Certificate: Data: Version: 3 (0x2) Serial Number: 7227871200284629574 (0x644e8e8fcf3dda46) Signature Algorithm: SHA256-RSA Issuer: O=the-ranch,CN=cattle-ca Validity Not Before: Jan 14 14:27:54 2020 UTC Not After : Jan 15 16:37:21 2021 UTC Subject: O=the-ranch,CN=cattle Subject Public Key Info: Public Key Algorithm: RSA Public-Key: (2048 bit) Modulus: ba:ee:fc:fb:b1:76:98:3d:58:59:bf:e2:bf:be:46: ab:c8:43:89:97:7a:0d:da:71:dd:25:c9:31:3c:86: 7e:97:1d:5a:3a:95:77:ba:6f:20:77:ea:8d:84:f9: 8a:a4:1b:3c:e5:79:c5:e3:5b:d2:c9:19:ef:6f:fe: e4:6e:e6:06:89:42:d2:81:e8:b1:b2:cf:96:18:4a: 41:cf:5e:4a:99:3c:c7:80:38:45:42:3f:fa:1c:0f: cf:a9:26:74:d6:8a:ab:62:c4:fd:8a:77:73:c8:d5: 76:40:eb:ff:72:4d:b1:85:cf:d5:8a:ca:8d:d3:a8: f4:b2:c3:77:2d:44:66:e0:b2:f4:3a:c3:3f:a1:0f: 56:4c:71:45:4d:da:d6:63:d1:64:f5:f6:14:a7:63: 44:56:08:61:47:20:34:33:c7:c0:71:92:1e:a1:61: 13:85:aa:5c:23:b3:74:bd:9f:07:e5:4f:10:0b:53: ad:50:44:ed:f1:60:32:a6:44:3d:9e:4f:64:46:28: 2d:e9:ef:fe:c1:df:59:3f:39:60:81:9c:c2:e0:d6: 1c:fd:a3:05:da:b4:6a:8e:a1:dd:1d:65:f9:6a:6d: 2c:84:d4:32:87:ba:1d:ea:cc:2f:ca:a8:20:e5:b0: ea:85:b4:cf:66:15:77:a3:9f:61:30:6a:3c:0d:e9: 83 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Subject Alternative Name: DNS: IP Address:18.204.194.218, IP Address:127.0.0.1, IP Address:169.254.169.254, IP Address:5.188.210.101, IP Address:23.205.25.30, IP Address:123.125.114.144 Signature Algorithm: SHA256-RSA 78:fb:ca:ff:ef:1d:3b:f4:6c:f7:f4:c7:12:6c:f5:f7:d2:4c: 95:71:b9:6c:f5:8c:42:83:35:1f:3d:c0:10:05:1f:7f:9e:80: 53:a6:e8:42:31:e9:a9:73:d4:84:b4:ca:cd:24:ae:55:9a:31: 28:91:9f:6f:d6:db:dc:b2:b8:2c:ea:46:2a:74:51:0e:07:63: d8:4e:47:17:1f:de:bd:4f:9e:34:36:5c:e3:ea:6c:ec:7b:fd: 7d:58:9d:d3:8a:88:6f:0d:b2:36:3d:a4:04:32:9a:0f:4a:2f: 29:f0:93:e1:4f:e1:37:f3:1d:1c:8b:5a:14:2a:ed:92:cb:3b: 14:39:c5:6d:5c:a5:4d:ff:aa:66:31:46:9f:ac:57:10:7f:ef: 14:b5:9d:d1:7b:3b:c4:8f:4a:06:15:b1:52:59:8b:78:49:3f: 9b:31:46:cd:63:21:03:4c:32:58:06:28:f6:7e:26:54:6c:1e: fb:5b:64:78:cc:99:1e:e6:95:78:14:f7:64:b5:da:1d:32:ec: ea:3c:49:4e:7e:a2:ca:15:96:e1:69:f8:18:8c:09:72:d0:78: c6:9e:4e:04:8e:96:01:88:d2:24:df:c3:8f:7d:c4:ec:43:01: e9:db:bc:d2:44:53:ee:e9:4a:e0:24:85:cb:82:d8:3c:8a:d4: 4b:dd:e9:1a ] Do you want to continue connecting (yes/no)? yes FATA[0012] Bad response statusCode [401]. Status [401 Unauthorized]. Body: [message=clusterID does not match] from [https://18.204.194.218/v3] With good token == N/A as scope, the message will be\nrancher login https://18.204.194.218/v3 --token token-k6c5s:g5sm********************************************stjv The authenticity of server \u0026#39;https://18.204.194.218\u0026#39; can\u0026#39;t be established. Cert chain is : [Certificate: Data: Version: 3 (0x2) Serial Number: 7227871200284629574 (0x644e8e8fcf3dda46) Signature Algorithm: SHA256-RSA .... DELETED Do you want to continue connecting (yes/no)? yes INFO[0005] Saving config to /Users/miro/.rancher/cli2.json Using Rancher CLI # After login I do not need to use kubeconfig for kubectl:\nrancher kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-5c98cb979f-bbhxf 1/1 Running 0 5d23h cattle-system cattle-node-agent-dwnxk 1/1 Running 0 5d23h cattle-system kube-api-auth-d4zgq 1/1 Running 0 5d23h ingress-nginx default-http-backend-67cf578fc4-grmsw 1/1 Running 0 5d23h ingress-nginx nginx-ingress-controller-mpnmb 1/1 Running 0 5d23h kube-system canal-jw85q 2/2 Running 0 5d23h kube-system coredns-5c59fd465f-47q5z 1/1 Running 0 5d23h kube-system coredns-autoscaler-d765c8497-sm5xf 1/1 Running 0 5d23h kube-system metrics-server-64f6dffb84-bp864 1/1 Running 0 5d23h kube-system rke-coredns-addon-deploy-job-95qnk 0/1 Completed 0 5d23h kube-system rke-ingress-controller-deploy-job-brv7w 0/1 Completed 0 5d23h kube-system rke-metrics-addon-deploy-job-tvt89 0/1 Completed 0 5d23h kube-system rke-network-plugin-deploy-job-7rqcr 0/1 Completed 0 5d23h ","date":"January 18, 2020","externalUrl":null,"permalink":"/posts/2020-01-18-rancher-cli/","section":"Posts","summary":"Accessing Rancher cluster # After creation, you can access the K8s cluster running Rancher by saving the config file available from the console and using standard kubectl command\nkubectl --kubeconfig ./quickstart.kubeconfig get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE cattle-system cattle-cluster-agent-5c98cb979f-bbhxf 1/1 Running 0 5d23h cattle-system cattle-node-agent-dwnxk 1/1 Running 0 5d23h cattle-system kube-api-auth-d4zgq 1/1 Running 0 5d23h ingress-nginx default-http-backend-67cf578fc4-grmsw 1/1 Running 0 5d23h ingress-nginx nginx-ingress-controller-mpnmb 1/1 Running 0 5d23h kube-system canal-jw85q 2/2 Running 0 5d23h kube-system coredns-5c59fd465f-47q5z 1/1 Running 0 5d23h kube-system coredns-autoscaler-d765c8497-sm5xf 1/1 Running 0 5d23h kube-system metrics-server-64f6dffb84-bp864 1/1 Running 0 5d23h kube-system rke-coredns-addon-deploy-job-95qnk 0/1 Completed 0 5d23h kube-system rke-ingress-controller-deploy-job-brv7w 0/1 Completed 0 5d23h kube-system rke-metrics-addon-deploy-job-tvt89 0/1 Completed 0 5d23h kube-system rke-network-plugin-deploy-job-7rqcr 0/1 Completed 0 5d23h The same information (and much more) is available using rancher CLI.\n","title":"Rancher CLI vs kubectl","type":"post"},{"content":"Time to make checkpoint number 1 - it is day 11 of 30.\nSo far - out of this 11 days I have 10 days with commits. The missing day was fully dedicated to working on presentation and documentation, that unfortunately ends up Confluence and Google Doc, not in some proper textual format (read: Markdown or RestructuredText) backed by a repository.\nStuff that I worked on:\nsome minor updates to resume (added AWS badges, fixed some typos) notes from certification courses + code fragments scripts for automation of documents / ebooks backup from iCloud to local drives Most commits went to documentation / practice code for my project \u0026ldquo;Many ways to Kubernetes\u0026rdquo; where I play with building up K8s clusters using different approaches. So far I did the \u0026ldquo;Kubernetes the hard way\u0026rdquo; - following the course from Linux Academy (https://linuxacademy.com/cp/modules/view/id/221),\nThis repo - https://gitlab.com/plg-containers/kubernetes-the-hard-way (https://plg-containers.gitlab.io/kubernetes-the-hard-way/) - is not public for now, as I need to make sure I am not violating any IP when building on code fragments from the course. Once I have time to review it, I will switch it to public.\nI have also played with several ways how Rancher can be set up and it is quite intriguing, considering the fact that it can be deployed as extension on top of proper K8s cluster as well as to start on Docker host and simulate the cluster by running K8s components in the Docker containers.\nTo sum it up: so far 10:1. Moving on.\n","date":"December 17, 2019","externalUrl":null,"permalink":"/posts/2019-12-17-30-day-commit-challenge-1/","section":"Posts","summary":"Time to make checkpoint number 1 - it is day 11 of 30.\nSo far - out of this 11 days I have 10 days with commits. The missing day was fully dedicated to working on presentation and documentation, that unfortunately ends up Confluence and Google Doc, not in some proper textual format (read: Markdown or RestructuredText) backed by a repository.\nStuff that I worked on:\nsome minor updates to resume (added AWS badges, fixed some typos) notes from certification courses + code fragments scripts for automation of documents / ebooks backup from iCloud to local drives Most commits went to documentation / practice code for my project “Many ways to Kubernetes” where I play with building up K8s clusters using different approaches. So far I did the “Kubernetes the hard way” - following the course from Linux Academy (https://linuxacademy.com/cp/modules/view/id/221),\n","title":"30 day commit challenge - Checkpoint 1","type":"post"},{"content":"","date":"December 17, 2019","externalUrl":null,"permalink":"/tags/30daychallenge/","section":"Tags","summary":"","title":"30daychallenge","type":"tags"},{"content":"","date":"December 11, 2019","externalUrl":null,"permalink":"/tags/hacking/","section":"Tags","summary":"","title":"Hacking","type":"tags"},{"content":"This is the scariest thing I have read since spring 2018:\nhttps://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5\nwritten by @david.gilbertson.\nIt pretty sure what he describes is actually happening, has been happening before he described it and will be happening going on - just obviously not in the named module. The ecosystem of Node modules is so vast and so unstable that considerable number of project do not do enough to catch behaviour like this.\nWhy is this important: security is not optional and project budgets simply do not count on extensive investigation over transitive closure of all dependencies. What makes it even worse, it is not a job that can be done and checked off for the duration of the product. Unless the depencies and their dependencies are frozen, it is very easy to grab newer version of a second or third level dependency that may infected.\nAnd also, it is not Node issue only. I can imagine Python will suffer same issues with its ecosystem as rich and as dynamic as it is today. Not everybody is using pipenv and freezing the library versions. And the same can be true for Java and JARs.\nDocker of course add completely different level to this by shipping binary images which can contain pretty much anything. Unless you use commercially scanned and validated images, verify SHA1 and review every source docker file and every package installed, you are not safe.\nReviewing dockerfile is not enough - as it is trivial to run clean and safe container, install something malicious and the commit the changes. If you cleverly tag the container, it may be picked up and spread.\nOne does not really need to doctor the image - all that is necessary is to find an exploit in useful Linux utility and then search which docker images installed it - and which images are using the contaminated one as base\nAnd when Kubernetes really becomes \u0026ldquo;OS of the cloud\u0026rdquo;, the new opportunities will emerges. Just check how many system or infrastructure containers you have when you install Istio, Dashboard, ArgoCD, Traefik etc etc. Can you be sure you trust these and know what is really running inside your cluster ?\nWe are living in dangerous times.\n","date":"December 11, 2019","externalUrl":null,"permalink":"/posts/2019-12-11-hackernoon/","section":"Posts","summary":"This is the scariest thing I have read since spring 2018:\nhttps://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5\nwritten by @david.gilbertson.\nIt pretty sure what he describes is actually happening, has been happening before he described it and will be happening going on - just obviously not in the named module. The ecosystem of Node modules is so vast and so unstable that considerable number of project do not do enough to catch behaviour like this.\n","title":"On harvesting credit card numbers and passwords","type":"post"},{"content":"","date":"December 11, 2019","externalUrl":null,"permalink":"/tags/security/","section":"Tags","summary":"","title":"Security","type":"tags"},{"content":"My work in last few years took my away from practical coding towards DevOps. Despite the increased role of IaaC in our DevOps, this often means living in iTerm and AWS console with interaction not being captured in any form.\nOn writing side, lots of my output shifted from code towards writing text in Wiki\u0026rsquo;s, GoogleDocs and more and more in Slack messages. The code I write are short one-liners or small scripts with very short life span. This makes me a bit sad as there is no sense of accomplishment at the end of the day or week. The git log does not work over Wiki, AWS console, iTerm, Slack and GoogleDrive.\nSo in the spirit of 30 day Challenges, I am starting today on Dec 6th the 30 day commit-every-day challenge to overcome this feeling.\nHere are the self imposed rules: # there will be at least one commit every day betweek Dec 6th and January 6th, inclusive Commit must show in the activity log in at least one of my 3 Cloud source repos: GitHub, GitLab or Bitbucket both public and private repos count (most of my stuff is still not open, but I am drifting towards public) The commits must be meaningful - no commits just for commits - and must represent at least one hour of coding or writing work. The gists / snippets count as long as they are in cloud (the SnippetsLab does not count) What I want to get out of all this: # I hope for four main benefits\nfeel good and start/re-enforce habit stimulate the motivation on writing more code and documentation in source code speed up the work on the certification preparation with practical examples to try improve extracting/capturing the reusable chunks of scripts into Gists, blog entries or tools Now, I said this publicly so there is no way back :-) - I am holding myself accountable to do this.\nSpeaking of accountability, it would be kinda boring to write every day micro-blog on the details, so I make commitment to publish 3 updates on progress - on:\n16th of December 2019 26th of December 2019 5th of January 2020 This kinda works well with my schedule - I plan to go for skiing trip to Dolomites in January.\nHere we go, end of Day 1.\n","date":"December 6, 2019","externalUrl":null,"permalink":"/posts/2019-12-06-30-day-commit-challenge/","section":"Posts","summary":"My work in last few years took my away from practical coding towards DevOps. Despite the increased role of IaaC in our DevOps, this often means living in iTerm and AWS console with interaction not being captured in any form.\nOn writing side, lots of my output shifted from code towards writing text in Wiki’s, GoogleDocs and more and more in Slack messages. The code I write are short one-liners or small scripts with very short life span. This makes me a bit sad as there is no sense of accomplishment at the end of the day or week. The git log does not work over Wiki, AWS console, iTerm, Slack and GoogleDrive.\n","title":"30 day commit challenge","type":"post"},{"content":"Today\u0026rsquo;s blog of the day is a special one. It does not deal with cloud, DevOps or distributed systems. The theme of the blog is travel, life of digital nomad and observations on life from a perspective of a smart young woman, working as Online English teacher and travelling a lot while doing so - https://bookandtravel.blog/\nWhat makes this blog dear and interesting to me is that it\u0026rsquo;s author is my daughter Silvia. What could make the blog interesting and valuable for other audience (especially those learning English who are interested in personal development) is the format of the entries - as they combine reading and language teaching. Each post contains 10-20 emphasized words or expressions that are explained in footnotes - check this one\nThis way you can learn not only about interesting places and how her generation sees the world, but also discover new nuances and interesting words (German would say Redewendungen) in English.\nBecause of our work we do not get to spend enough time with our children, so I am grateful for any channel that allows me to be part of their lives. Like this blog and her Instagram channel - https://www.instagram.com/sadamyova/\n","date":"December 5, 2019","externalUrl":null,"permalink":"/posts/2019-12-05-silvias-blog/","section":"Posts","summary":"Today’s blog of the day is a special one. It does not deal with cloud, DevOps or distributed systems. The theme of the blog is travel, life of digital nomad and observations on life from a perspective of a smart young woman, working as Online English teacher and travelling a lot while doing so - https://bookandtravel.blog/\nWhat makes this blog dear and interesting to me is that it’s author is my daughter Silvia. What could make the blog interesting and valuable for other audience (especially those learning English who are interested in personal development) is the format of the entries - as they combine reading and language teaching. Each post contains 10-20 emphasized words or expressions that are explained in footnotes - check this one\n","title":"BOTD - Blog of the Day","type":"post"},{"content":"","date":"December 5, 2019","externalUrl":null,"permalink":"/tags/europe/","section":"Tags","summary":"","title":"Europe","type":"tags"},{"content":"","date":"December 5, 2019","externalUrl":null,"permalink":"/tags/languages/","section":"Tags","summary":"","title":"Languages","type":"tags"},{"content":"","date":"December 5, 2019","externalUrl":null,"permalink":"/categories/travel/","section":"Categories","summary":"","title":"Travel","type":"categories"},{"content":"Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth.\n― Marcus Aurelius , Meditations ","date":"November 26, 2019","externalUrl":null,"permalink":"/posts/2019-11-26-totd/","section":"Posts","summary":"Everything we hear is an opinion, not a fact. Everything we see is a perspective, not the truth.\n― Marcus Aurelius , Meditations ","title":"Quote of the day","type":"post"},{"content":"","date":"November 26, 2019","externalUrl":null,"permalink":"/tags/quotes/","section":"Tags","summary":"","title":"Quotes","type":"tags"},{"content":"","date":"November 26, 2019","externalUrl":null,"permalink":"/tags/stoicism/","section":"Tags","summary":"","title":"Stoicism","type":"tags"},{"content":"Lovely November day in Valencia\n","date":"November 24, 2019","externalUrl":null,"permalink":"/posts/2019-11-24-valencia/","section":"Posts","summary":"Lovely November day in Valencia\n","title":"November in Valencia","type":"post"},{"content":"","date":"November 24, 2019","externalUrl":null,"permalink":"/tags/valencia/","section":"Tags","summary":"","title":"Valencia","type":"tags"},{"content":" Parallel building challenges # Unlike Github, Gitlab considers Hugo blogs first class citizens and does not impose any restrictions on repo naming.\nI had 3 challenges to overcome related to co-existence of GH and GL versions:\nI need to use same repo for both GH and GL the submodule link for public does not work on GL the site root is different - I have no custom domain forward for GitLab Using same repo # To separate the GH and GL, I have added 2 remotes to repo and special branch gitlab-pages.\nSo the local repo looks like this:\n➜ miroadamy.com git:(master) ✗ git remote -v -v github git@github.com:miroadamy/miroadamy.com.git (fetch) github git@github.com:miroadamy/miroadamy.com.git (push) origin git@gitlab.com:miro.adamy/miroadamy.com.git (fetch) origin git@gitlab.com:miro.adamy/miroadamy.com.git (push) The branch gitlab-pages is \u0026ldquo;superset\u0026rdquo; of master. This means that I am always merging master =\u0026gt; gitlab-pages but never the other way around.\nThe consequence is that GL version can have more posts than GH and as GL version is private, it is OK.\nPublishing process and public # GL allows simple pipeline that generates the site into public folder. The submodule does not need to exist. Actually, it cannot exists, as it would be breaking the build.\nHere is the file .gitlab-ci.yml\nimage: monachus/hugo variables: GIT_SUBMODULE_STRATEGY: recursive pages: script: - mkdir -p public - hugo --baseURL https://miro.adamy.gitlab.io/miroadamy.com/ artifacts: paths: - public only: - gitlab-pages The pipeline runs ONLY for gitlab-pages branch and resulting pages can be seen at https://miro.adamy.gitlab.io/miroadamy.com/ (this is currently private).\nRemoving the submodules # I used this as opportunity to clean the unused themes from the blog:\n# Step 1 - deinit repos ➜ miroadamy.com git:(gitlab-pages) ✗ git submodule deinit themes/ananke Cleared directory \u0026#39;themes/ananke\u0026#39; Submodule \u0026#39;themes/ananke\u0026#39; (https://github.com/budparr/gohugo-theme-ananke.git) unregistered for path \u0026#39;themes/ananke\u0026#39; ➜ miroadamy.com git:(gitlab-pages) ✗ git submodule deinit themes/hugo-coder Cleared directory \u0026#39;themes/hugo-coder\u0026#39; Submodule \u0026#39;themes/hugo-coder\u0026#39; (https://github.com/luizdepra/hugo-coder.git) unregistered for path \u0026#39;themes/hugo-coder\u0026#39; ➜ miroadamy.com git:(gitlab-pages) ✗ git submodule deinit public Cleared directory \u0026#39;public\u0026#39; Submodule \u0026#39;public\u0026#39; (git@github.com:miroadamy/miroadamy.github.io.git) unregistered for path \u0026#39;public\u0026#39; # Step 2 - delete the files ➜ miroadamy.com git:(gitlab-pages) ✗ rm -rf themes/ananke ➜ miroadamy.com git:(gitlab-pages) ✗ rm -rf themes/hugo-coder ➜ miroadamy.com git:(gitlab-pages) rm -rf public # Step 3 - delete the parts of `.gitmodules` From THIS ➜ miroadamy.com git:(gitlab-pages) ✗ cat .gitmodules [submodule \u0026#34;themes/ananke\u0026#34;] path = themes/ananke url = https://github.com/budparr/gohugo-theme-ananke.git [submodule \u0026#34;themes/hugo-coder\u0026#34;] path = themes/hugo-coder url = https://github.com/luizdepra/hugo-coder.git [submodule \u0026#34;themes/even\u0026#34;] path = themes/even url = https://github.com/olOwOlo/hugo-theme-even [submodule \u0026#34;public\u0026#34;] path = public url = git@github.com:miroadamy/miroadamy.github.io.git To THIS ➜ miroadamy.com git:(master) ✗ cat .gitmodules [submodule \u0026#34;themes/even\u0026#34;] path = themes/even url = https://github.com/olOwOlo/hugo-theme-even # Step 4 git add -u git commit git push Result # publishing to GH works as before =\u0026gt; run \u0026lsquo;./publish.sh\u0026rsquo; publishing to GL happens on any push to branch \u0026lsquo;gitlab-pages\u0026rsquo; getting changes from GH to GL: # Sync up master on both git checkout master git pull github git push origin master # Get the gitlab-pages git checkout gitlab-pages git pull origin git merge master git push origin gitlab-pages # optionally, may want to push to GH as well git push github gitlab-pages ","date":"November 23, 2019","externalUrl":null,"permalink":"/posts/2019-11-23-gitlab-hugo/","section":"Posts","summary":"Parallel building challenges # Unlike Github, Gitlab considers Hugo blogs first class citizens and does not impose any restrictions on repo naming.\nI had 3 challenges to overcome related to co-existence of GH and GL versions:\nI need to use same repo for both GH and GL the submodule link for public does not work on GL the site root is different - I have no custom domain forward for GitLab Using same repo # To separate the GH and GL, I have added 2 remotes to repo and special branch gitlab-pages.\n","title":"Building Hugo as well on GitLab pages","type":"post"},{"content":"","date":"November 23, 2019","externalUrl":null,"permalink":"/tags/gitlab/","section":"Tags","summary":"","title":"Gitlab","type":"tags"},{"content":"","date":"November 23, 2019","externalUrl":null,"permalink":"/tags/hugo/","section":"Tags","summary":"","title":"Hugo","type":"tags"},{"content":" How does the blog setup and publishing work # Before I forget, here is how the current configuration works.\nThere are two repositories at play:\nsource repo - https://github.com/miroadamy/miroadamy.com github pages repo (== GHPR) - https://github.com/miroadamy/miroadamy.github.io The blog source repo contains only source files (.md, static media etc). This repo has usual submodules under the /themes - e.g. /themes/even which is one currently used.\nThe Githup pages repo contains generated static site, with index.html that can be theoretically deployed in any hosting site or S3 bucket. Every push against the GHPR will be immediately visible.\nAs per Github pages requirements, the repository MUST have name USERNAME.github.io.\nSite generation # The Hugo generator processes the source code using configuration file and writes output - static generated site - under ./public subfolder.\nTo make things easier I have checked out the GHPR repository as submodule of source repo under ./public in the source repo. The tree of the repos looks like this\n➜ miroadamy.com git:(master) ✗ tree -F -L 1 . =\u0026gt; github.com:miroadamy/miroadamy.com ├── archetypes/ ├── config.toml ├── config.toml~ ├── content/ ├── data/ ├── layouts/ ├── public/ =\u0026gt; github.com:miroadamy/miroadamy.github.io.gi ├── resources/ ├── static/ └── themes/ ├── ananke/ =\u0026gt; github.com:budparr/gohugo-theme-ananke.git (not used) ├── even/ =\u0026gt; github.com:olOwOlo/hugo-theme-even └── hugo-coder/ =\u0026gt; github.com:luizdepra/hugo-coder.git (not used) The .gitmodules files shows the same information\n[submodule \u0026#34;themes/ananke\u0026#34;] path = themes/ananke url = https://github.com/budparr/gohugo-theme-ananke.git [submodule \u0026#34;themes/hugo-coder\u0026#34;] path = themes/hugo-coder url = https://github.com/luizdepra/hugo-coder.git [submodule \u0026#34;themes/even\u0026#34;] path = themes/even url = https://github.com/olOwOlo/hugo-theme-even [submodule \u0026#34;public\u0026#34;] path = public url = git@github.com:miroadamy/miroadamy.github.io.git Publishing new version of the blog # The generation step from source to GHPR is done locally - I want to test the result before publishing anyway so I need to have local Hugo setup\nSteps\nEdit the source Test locally - hugo serve - runs local server and allows to validate on https://localhost:1313/ Repeat The start of Hugo is very fast \u0026lt; 1 sec. It generates site to temporary space and starts embedded webserver on port 1313\n➜ miroadamy.com git:(master) ✗ hugo serve | EN +------------------+-----+ Pages | 527 Paginator pages | 149 Non-page files | 1 Static files | 200 Processed images | 0 Aliases | 41 Sitemaps | 1 Cleaned | 0 Total in 541 ms Watching for changes in /Users/miro/src/MIA/miroadamy.com/{archetypes,content,data,layouts,static,themes} Watching for config changes in /Users/miro/src/MIA/miroadamy.com/config.toml Environment: \u0026#34;development\u0026#34; Serving pages from memory Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender Web Server is available at http://localhost:1313/ (bind address 127.0.0.1) Press Ctrl+C to stop During development, we can edit the source files and changes are immediately reflected in rendered site. This allows super fast development.\nWhen the content looks good, we generate the static content into ./public. This writes new content to the GHPR repo. Here are the steps used for this article:\n# In the source repository ➜ miroadamy.com git:(master) ✗ pwd /Users/miro/src/MIA/miroadamy.com # Note the added file - we have validated that all is OK by running `hugo serve` and localhost:1313 ➜ miroadamy.com git:(master) ✗ gss ?? content/posts/2019-11-22-hugo-setup.md # Now we generate the site ➜ miroadamy.com git:(master) ✗ hugo | EN +------------------+-----+ Pages | 527 Paginator pages | 149 Non-page files | 1 Static files | 200 Processed images | 0 Aliases | 41 Sitemaps | 1 Cleaned | 0 Total in 679 ms # Note that there is additonal change - the `public` link has been modified # We are now in context of source repo: ➜ miroadamy.com git:(master) ✗ git remote -v origin git@github.com:miro.adamy/miroadamy.com.git (fetch) origin git@github.com:miro.adamy/miroadamy.com.git (push) # Go to public =\u0026gt; here we will be in context of GHPR ➜ miroadamy.com git:(master) ✗ cd public ➜ public git:(master) ✗ git remote -v origin git@github.com:miroadamy/miroadamy.github.io.git (fetch) origin git@github.com:miroadamy/miroadamy.github.io.git (push) # The generator modified lots of files and added some. We need to commit these changes ➜ public git:(master) ✗ git add . ➜ public git:(master) ✗ git status On branch master Your branch is up-to-date with \u0026#39;origin/master\u0026#39;. Changes to be committed: (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) modified: categories/index.html modified: categories/index.xml modified: categories/programming/index.html modified: categories/programming/index.xml modified: index.html modified: index.xml modified: page/10/index.html modified: page/11/index.html modified: page/12/index.html modified: page/13/index.html modified: page/14/index.html modified: page/15/index.html modified: page/16/index.html modified: page/17/index.html modified: page/18/index.html modified: page/19/index.html modified: page/2/index.html modified: page/20/index.html modified: page/21/index.html modified: page/22/index.html modified: page/23/index.html modified: page/24/index.html modified: page/25/index.html modified: page/26/index.html modified: page/27/index.html modified: page/28/index.html modified: page/29/index.html modified: page/3/index.html modified: page/30/index.html modified: page/31/index.html modified: page/32/index.html modified: page/33/index.html modified: page/34/index.html modified: page/35/index.html modified: page/36/index.html modified: page/37/index.html modified: page/38/index.html modified: page/39/index.html modified: page/4/index.html modified: page/40/index.html modified: page/41/index.html modified: page/42/index.html modified: page/43/index.html modified: page/44/index.html modified: page/45/index.html modified: page/46/index.html modified: page/47/index.html modified: page/48/index.html modified: page/49/index.html modified: page/5/index.html modified: page/50/index.html modified: page/51/index.html modified: page/52/index.html modified: page/53/index.html modified: page/54/index.html modified: page/55/index.html modified: page/56/index.html modified: page/57/index.html modified: page/58/index.html modified: page/59/index.html modified: page/6/index.html modified: page/60/index.html modified: page/61/index.html modified: page/62/index.html modified: page/63/index.html modified: page/64/index.html modified: page/65/index.html modified: page/66/index.html modified: page/67/index.html modified: page/68/index.html modified: page/69/index.html modified: page/7/index.html modified: page/70/index.html modified: page/71/index.html modified: page/72/index.html modified: page/73/index.html modified: page/74/index.html modified: page/75/index.html modified: page/76/index.html modified: page/77/index.html modified: page/78/index.html modified: page/79/index.html modified: page/8/index.html modified: page/80/index.html modified: page/81/index.html modified: page/82/index.html modified: page/83/index.html modified: page/84/index.html modified: page/85/index.html modified: page/86/index.html modified: page/87/index.html modified: page/88/index.html modified: page/9/index.html modified: posts/2019-11-20-from-jekyll-to-hugo/index.html new file: posts/2019-11-22-hugo-setup/index.html new file: posts/2029-01-01-post.md.template modified: posts/index.html modified: posts/index.xml modified: posts/page/10/index.html modified: posts/page/11/index.html modified: posts/page/12/index.html modified: posts/page/13/index.html modified: posts/page/14/index.html modified: posts/page/15/index.html modified: posts/page/16/index.html modified: posts/page/17/index.html modified: posts/page/18/index.html modified: posts/page/19/index.html modified: posts/page/2/index.html modified: posts/page/20/index.html modified: posts/page/21/index.html modified: posts/page/22/index.html modified: posts/page/23/index.html modified: posts/page/24/index.html modified: posts/page/25/index.html modified: posts/page/26/index.html modified: posts/page/27/index.html modified: posts/page/28/index.html modified: posts/page/29/index.html modified: posts/page/3/index.html modified: posts/page/30/index.html modified: posts/page/31/index.html modified: posts/page/32/index.html modified: posts/page/33/index.html modified: posts/page/34/index.html modified: posts/page/35/index.html modified: posts/page/36/index.html modified: posts/page/37/index.html modified: posts/page/38/index.html modified: posts/page/39/index.html modified: posts/page/4/index.html modified: posts/page/40/index.html modified: posts/page/41/index.html modified: posts/page/42/index.html modified: posts/page/43/index.html modified: posts/page/44/index.html modified: posts/page/5/index.html modified: posts/page/6/index.html modified: posts/page/7/index.html modified: posts/page/8/index.html modified: posts/page/9/index.html modified: sitemap.xml modified: tags/blog/index.html modified: tags/blog/index.xml modified: tags/blog/page/2/index.html modified: tags/blog/page/3/index.html modified: tags/index.html modified: tags/index.xml # Make local commit ➜ public git:(master) ✗ git commit -m \u0026#34;Published the Hugo setup article\u0026#34; [master cd95809] Published the Hugo setup article 148 files changed, 3219 insertions(+), 2638 deletions(-) create mode 100644 posts/2019-11-22-hugo-setup/index.html create mode 100644 posts/2029-01-01-post.md.template # Publish site on Github ➜ public git:(master) git push Counting objects: 291, done. Delta compression using up to 8 threads. Compressing objects: 100% (157/157), done. Writing objects: 100% (291/291), 131.31 KiB | 0 bytes/s, done. Total 291 (delta 150), reused 0 (delta 0) remote: Resolving deltas: 100% (150/150), completed with 61 local objects. To github.com:miroadamy/miroadamy.github.io.git 676432b..cd95809 master -\u0026gt; master # Now the static site was updated but the source needs to be as well ➜ miroadamy.com git:(master) ✗ git status On branch master Your branch is ahead of \u0026#39;origin/master\u0026#39; by 1 commit. (use \u0026#34;git push\u0026#34; to publish your local commits) Changes not staged for commit: (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) (use \u0026#34;git checkout -- \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) modified: public (new commits) Untracked files: (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to include in what will be committed) content/posts/2019-11-22-hugo-setup.md no changes added to commit (use \u0026#34;git add\u0026#34; and/or \u0026#34;git commit -a\u0026#34;) # We add the changes to source - new changed file as well as the \u0026#39;public\u0026#39; link ➜ miroadamy.com git:(master) ✗ git add . ➜ miroadamy.com git:(master) ✗ git commit -m \u0026#34;Published the Hugo setup article source\u0026#34; [master f078d54] Published the Hugo setup article source 2 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 content/posts/2019-11-22-hugo-setup.md And we are done\nIt can be automated to this small script:\n#!/bin/bash MESSAGE=${1:-\u0026#39;Published changes\u0026#39;} hugo cd public git add . git commit -m \u0026#34;$MESSAGE\u0026#34; git push cd .. git add . git commit -m \u0026#34;${MESSAGE} - source\u0026#34; git push ","date":"November 22, 2019","externalUrl":null,"permalink":"/posts/2019-11-22-hugo-setup/","section":"Posts","summary":"How does the blog setup and publishing work # Before I forget, here is how the current configuration works.\nThere are two repositories at play:\nsource repo - https://github.com/miroadamy/miroadamy.com github pages repo (== GHPR) - https://github.com/miroadamy/miroadamy.github.io The blog source repo contains only source files (.md, static media etc). This repo has usual submodules under the /themes - e.g. /themes/even which is one currently used.\n","title":"Current Hugo setup on Github Pages","type":"post"},{"content":"","date":"November 22, 2019","externalUrl":null,"permalink":"/tags/plaintext/","section":"Tags","summary":"","title":"Plaintext","type":"tags"},{"content":"I have decided to consolidate all piecemeal versions of my blogpost uder one roof and at the same to do these four things\ntechnology upgrade - from Jekyll to Hugo visual refresh of the page review tagging and categorization merge hidden posts from Wikis to one place Why Hugo replaced Jekyll # The version 3 of my blog (see below for a bit of history) has been hosted on Github pages and using the default static site generators - Jekyll.\nA bit of history # I started to keep my notes on things of interest long long time ago - in 2006, shortly after we founded Thinknostic.\nVersion 1 - Wordpress # When I started blogging back in 2006, it was Thinknostic second year and we started to really grow: we got our own space beyond small sales office in downtown we have had before, built some serious hardware infrastructure, employee numbers started to go into two digit territory and we landed our first 1 M$+ project. My blog at http://thinkwrap.wordpress.com/ was our unofficial presence in the social space. In 2006 I picked the login and account name “thinkwrap”, because it was – at that time – a word that kind-of expressed the approach we were using: something between methodology, best practices and a toolset.\nIn the three years, the same word ThinkWrap was selected as the new brand when Thinknostic in Ottawa and Pentura Solutions in Toronto (both “second life” companies of Montage origin) merged. Now suddenly, with “thinkwrap” in URL, my blog became whole lot more company-bound that I wanted. As everybody can see on dropping rate of contributions, I found pretty hard to post. I was never quite sure whether I really want to present my personal opinion to appear under ThinkWrap brand as something that the company would be saying. Even worse, now we were several times the size as before, with headcount of about 50 – who was I to speak for all these people, when there were so many smarter, more talented and more experienced than myself ?\nAs result, the whole blog thing came to a big halt – no posts for over 6 months. The only solution I could come up with was restart. Thus, a new, real corporate blog was created in 2009 that represented way more than single guy’s opinion. I was one of the contributors.\nThe blog http://thinkwrap.wordpress.com/ is still out there and ends in 2009 with the post The Fork at the end of this blog.\nThe https://blog.thinkwrap.com/ evolved over years into something much more corporate-ish and enterprise-ish and eventually disappeared with Thinkwrap purchase by Tenzing.\nVersion 2 - 2 blogs in Wordpress # After stoppin the use of http://thinkwrap.wordpress.com/ for my personal stuff, I have exported and reimported the content into different WordPress blog and hooked it under domain that clearly indicates that it was my personal blog and personal opinions: https://miroadamy.wordpress.com/\nThis blog is still out there and it\u0026rsquo;s \u0026ldquo;separate existence\u0026rdquo; started with this post in December 2009.\nCompared with the first blog, there is much less content. I was not really writing less, but most of what I wrote ended up in Wiki\u0026rsquo;s and Intranet and never made it to the blog.\nAlso, Wordpress was more and more an obstacle - and the fact that my texts live in some form of database instead of a source control system was really bugging me. So in 2013 I made first attempt to leave Wordpress platform and switch to repository driven approach (today we would say \u0026ldquo;blog as a code\u0026rdquo;).\nDuring this time, I become bit fan of plain text and markup formats and lots of my notes, internal blogs etc were originating as Markdown or AsciiDoc - which turned up to be a good thing in the end.\nVersion 2.5 - Gollum and Github Wiki # Well, the first attempt did not take. I tried to use Wiki pages in Github attached to the repository https://github.com/miroadamy/miroadamy-dot-com. It did not work well - wiki is NOT good platform for this kind of content - and after short time I learned how to use Github pages with custom domain. The miroadamy-dot-com is archived now.\nVersion 3 - Jekyll and Github pages with custom domain # The blog https://www.miroadamy.com/ existed in Jekyll incarnation from 2013 to November 2019. The look and feel was a bit plain and lots of posts were not included in the public version. It worked OK (mostly).\nI had three major issues with with this setup:\nJekyll is based on Ruby and I was trying to go away from the environments that need native modules / libraries (== gems) - I have enough headaches with Python libraries and JARs. Local development with Jekyll was a bit cumbersome and it was SLOW =\u0026gt; regenerating site took tens of seconds. Not good. consolidation of the internal Markdown files would be quite unpleasant with the above I really wanted to try Hugo :-) Version 4 - Hugo with Github pages hosting # This is current state - site was migrated (see next post on technical details) and published in the place of the old site. For visual refresh, I settled for the theme Even - https://github.com/olOwOlo/hugo-theme-even. I do not know whether I will keep it or not, but before playing with themes I need to finish #4 and #3 above.\n","date":"November 20, 2019","externalUrl":null,"permalink":"/posts/2019-11-20-from-jekyll-to-hugo/","section":"Posts","summary":"I have decided to consolidate all piecemeal versions of my blogpost uder one roof and at the same to do these four things\ntechnology upgrade - from Jekyll to Hugo visual refresh of the page review tagging and categorization merge hidden posts from Wikis to one place Why Hugo replaced Jekyll # The version 3 of my blog (see below for a bit of history) has been hosted on Github pages and using the default static site generators - Jekyll.\n","title":"From Jekyll to Hugo","type":"post"},{"content":"","date":"November 20, 2019","externalUrl":null,"permalink":"/tags/jekyll/","section":"Tags","summary":"","title":"Jekyll","type":"tags"},{"content":"“The older you get, the more quiet you become.\nLife humbles you so deeply as you age. You realize how much nonsense you’ve wasted time on.”\n\u0026mdash; Vala Afshar (@ValaAfshar) November 14, 2019 Adding screenshot in case the account disappears\n","date":"November 14, 2019","externalUrl":null,"permalink":"/posts/2019-11-14-totd/","section":"Posts","summary":"“The older you get, the more quiet you become.\nLife humbles you so deeply as you age. You realize how much nonsense you’ve wasted time on.”\n— Vala Afshar (@ValaAfshar) November 14, 2019 Adding screenshot in case the account disappears\n","title":"Thought of the day","type":"post"},{"content":"","date":"November 14, 2019","externalUrl":null,"permalink":"/tags/twitter/","section":"Tags","summary":"","title":"Twitter","type":"tags"},{"content":" All Day DevOps 2019 - Notes # I have attended the All Day Devops - https://www.alldaydevops.com/ on 06 Nov 2019 - an event that runs for 24 hours and has multiple tracks of content organized in 4 blocks.\nThe tracks:\nKeynotes Cultural Change DevSecOps SRE CI/CD Everything Cloud The complete list is here: https://www.alldaydevops.com/2019-live-schedule - the play button points to the block video.\nThe Video URLs # Channel 1 # https://www.youtube.com/watch?v=sHNgvs_lVzg https://www.youtube.com/watch?v=Nu5KLZwmYRI https://www.youtube.com/watch?v=zc9z2_ZwP4o https://www.youtube.com/watch?v=EXMND7WCiLc https://www.youtube.com/watch?v=56aA3A9igvw Channel 2 # https://www.youtube.com/watch?v=-JuPprlGb48 https://www.youtube.com/watch?v=D38NGcjLH_g https://www.youtube.com/watch?v=aIHaLiUw8oM https://www.youtube.com/watch?v=zTRN120Uu28 https://www.youtube.com/watch?v=gOLQ-7tL4v8 https://www.youtube.com/watch?v=qu9_HyW2uRM Channel 3 # https://www.youtube.com/watch?v=lZTMkEA7jws https://www.youtube.com/watch?v=jn8Xv8SiisM https://www.youtube.com/watch?v=Zyj0DgnseEg https://www.youtube.com/watch?v=khFkvYIFiIA https://www.youtube.com/watch?v=uymSPlasd6U https://www.youtube.com/watch?v=nYTGKeVzUBs Channel 4 # https://www.youtube.com/watch?v=xtNx1t6lxQE https://www.youtube.com/watch?v=Xzbk2pt0ilk https://www.youtube.com/watch?v=PVli8qvXgkM https://www.youtube.com/watch?v=YS0Axx5SggY https://www.youtube.com/watch?v=Bs-rzOmxa48 Channel 5 # https://www.youtube.com/watch?v=ike3vQbE4zc https://www.youtube.com/watch?v=WXINx5rEl4Q https://www.youtube.com/watch?v=a5J3CRWSOXA https://www.youtube.com/watch?v=N_A2uJzVZ8c https://www.youtube.com/watch?v=6GO9h1VsXc4 https://www.youtube.com/watch?v=HmjvBIuC-BQ Alltogether this represents about 5 x ~ 20 =~ over 100 hours of content.\nNoteworthy and 100% relevant to == my top 3 # This is subjective selection of those presentation that I managed to see and considered interesting plus with quick note why\n10:00 AM - Can Kubernetes Keep a Secret? - Omer Levi Hevroni # Link - https://www.youtube.com/watch?v=xtNx1t6lxQE\nAddresses issue we are having: Secret in YAML =\u0026gt; base 64 =\u0026gt; not secure =\u0026gt; not in Git\nEvaluated: Helm Secrets Sealed Secrets Kubeseal Seal = single key pair Helm secrets = Mozila Mops == coupled to cluster Required: Gitops, Native, secure vaultproject.io =\u0026gt; $$$, access control, no gitops flow =\u0026gt; imperfect Travis encrypted secrets =\u0026gt; only for given repo SOLUTION: Kamus =\u0026gt; Soluto (Kamus == secret in Hebrew) https://github.com/Soluto/kamus\nencrypt secrets for specific app, only that can decrypt it =\u0026gt; on AWS KMS, HSM support CRD support Application identity: service account, token helm install kamus soluto/kamus 11:00 AM - What You See Is What You Get For AWS Infrastructure - Anton Babenko # Awesome extension of Cloudcraft.io that genarates Terraform and Terragrunt code\nhttps://www.youtube.com/watch?v=xtNx1t6lxQE https://github.com/antonbabenko/modules.tf-lambda ‑ https://github.com/antonbabenko/modules.tf-demo ‑ Gitops FTW # https://www.youtube.com/watch?v=EXMND7WCiLc\u0026feature=youtu.be\u0026t=3843\n=\u0026gt; Our current workflow is based on GitOps\nNoteworthy and interesting # 10:00 AM - Multi Cloud \u0026ldquo;Day to Day\u0026rdquo; DevOps Power Tools- Ronen Freeman 10:30 AM - Bring Back the Power of the IDE: Debugging Apps Running in Kubernetes Jeff Knurek Bunch of notes and links # (should be sorted out - work in progress, saving them here)\nConcourse - deliver, extensible with bash Helm https://github.com/Darillium/addo-demo https://www.slideshare.net/TanyaJanca/devsecops-with-owasp-devslop-190667649 ---- Fergal Dearle (EC) https://www.linkedin.com/in/fergaldearle/ Templating for CFN https://github.com/Sceptre/sceptre ----- Jeff - travel audience https://github.com/jeff-knurek/all-day-devops-2019 Armador == docker compose for K8s Voting apps Telepresence =\u0026gt; tunnel from K8s to machine ksync vapor-ware squash solo-io skaffold cloud code ---- Kris Buytaert https://www.youtube.com/watch?v=lZTMkEA7jws \u0026#39;Bunch of guys go/nogo\u0026#39; 7 tools =\u0026gt; implement all tools ----- Rene van Osnabrugge ----- Jason Gwartz https://www.ecosia.org/ ---- Derek Weeks dependencies downloaded ---- Mohamed Labouardy https://github.com/mlabouardy/alldaydevops-ui-2019 https://github.com/mlabouardy/alldaydevops-engine-2019 https://github.com/mlabouardy/nexususerconference-infrastructure https://www.alldaydevops.com/blog/ci/cd-for-serverless-applications-on-aws ==== Ariane Gadd AWS Fargate KPMG CloudOps, 70% AWS ----- Sean O\u0026#39;Dell https://www.cloudjourney.io/ AWS functions https://github.com/theseanodell Amplify https://github.com/vmwarecloudadvocacy/cloudhealth-lambda-functions https://www.slideshare.net/SeanODell8/automate-everyday-tasks-with-functions-191076868 ------ https://www.youtube.com/watch?v=Xzbk2pt0ilk Jesse Butler https://noti.st/jlbutler https://noti.st/explore Stateful apps - https://www.youtube.com/watch?v=PVli8qvXgkM Bahubali Shet https://www.slideshare.net/BahubaliShetti/how-to-manage-state-with-a-kubernetes-application AKS - https://www.kubeflow.org/docs/notebooks/why-use-jupyter-notebook/ Jenkins - David Malett https://github.com/dmaillet63/sample/blob/master/Jenkinsfile file:///Users/miro/Downloads/ADDO_2019_CICD_Flexibility%20with%20Groovy-DavidMaillet.pdf J2EE Docker https://github.com/m-reza-rahman/javaee-docker 3 Musketeers: Jenkins, Terraform, Vault https://youtu.be/PVli8qvXgkM?t=5725 ","date":"November 7, 2019","externalUrl":null,"permalink":"/posts/2019-11-07-all-day-devops/","section":"Posts","summary":"All Day DevOps 2019 - Notes # I have attended the All Day Devops - https://www.alldaydevops.com/ on 06 Nov 2019 - an event that runs for 24 hours and has multiple tracks of content organized in 4 blocks.\nThe tracks:\nKeynotes Cultural Change DevSecOps SRE CI/CD Everything Cloud The complete list is here: https://www.alldaydevops.com/2019-live-schedule - the play button points to the block video.\n","title":"All Day DevOps 2019","type":"post"},{"content":"","date":"November 7, 2019","externalUrl":null,"permalink":"/tags/gitops/","section":"Tags","summary":"","title":"Gitops","type":"tags"},{"content":" Bunch of one-liners for AWS # .. so that I find them faster next time\naws --output=json ec2 describe-instances | jq -r \u0026#39;.Reservations[].Instances[] | \u0026#34;\\n\u0026#34; + .InstanceId + \u0026#34; : \u0026#34; + .KeyName + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress + \u0026#34; | \u0026#34; + .PublicDnsName, .Tags[] as $tt | \u0026#34; ... \u0026#34; + $tt.Key +\u0026#34;:\u0026#34;+ $tt.Value\u0026#39; aws ec2 describe-instances | jq \u0026#39;.Reservations[].Instances[] | .InstanceId + \u0026#34; : \u0026#34; + .Placement.AvailabilityZone + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress\u0026#39; aws iam list-group-policies --group-name kops aws ec2 describe-vpcs | jq \u0026#39;.Vpcs[] | .VpcId + \u0026#34; \u0026#34; + .CidrBlock\u0026#39; aws iam list-users | jq \u0026#39;.Users[].UserName\u0026#39; aws --output=json --region=ca-central-1 ec2 describe-vpcs | jq -r \u0026#39;.Vpcs[] | .VpcId + \u0026#34; \u0026#34; + .CidrBlock,.Tags[] as $tt | \u0026#34; .. \u0026#34; + $tt.Key +\u0026#34;:\u0026#34;+$tt.Value\u0026#39; aws ec2 describe-vpcs | jq -e --raw-output \u0026#39;.Vpcs[] | \u0026#34;\\n\u0026#34; + .VpcId + \u0026#34; : \u0026#34; + .CidrBlock, .Tags[] as $tt | \u0026#34; ... \u0026#34; + $tt.Key +\u0026#34;:\u0026#34;+ $tt.Value\u0026#39; aws ec2 describe-subnets | jq -e --raw-output \u0026#39;.Subnets[] | \u0026#34;\\n\u0026#34; + .VpcId + \u0026#34; : \u0026#34; + .CidrBlock +\u0026#34; : \u0026#34; + .AvailabilityZone, .Tags[] as $tt | \u0026#34; ... \u0026#34; + $tt.Key +\u0026#34;:\u0026#34;+ $tt.Value\u0026#39; aws ec2 authorize-security-group-ingress --group-id sg-bfa45bd4 --protocol tcp --port 31672 --cidr 204.101.219.210/31 How many instances of each type do I have, and in what states? # Considering buying reserved instances or thinking about migrating to a newly introduced class? aws ec2 describe-instances | jq -r \u0026#34;[[.Reservations[].Instances[]|{ state: .State.Name, type: .InstanceType }]|group_by(.state)|.[]|{state: .[0].state, types: [.[].type]|[group_by(.)|.[]|{type: .[0], count: ([.[]]|length)}] }]\u0026#34; What CIDRs have Ingress Access to which Ports? # # This is helpful when you need to perform a survey or audit of your system boundaries. While such a task isn’t ever “easy”, it can go more smoothly with with a summary: aws ec2 describe-security-groups | jq \u0026#39;[ .SecurityGroups[].IpPermissions[] as $a | { \u0026#34;ports\u0026#34;: [($a.FromPort|tostring),($a.ToPort|tostring)]|unique, \u0026#34;cidr\u0026#34;: $a.IpRanges[].CidrIp } ] | [group_by(.cidr)[] | { (.[0].cidr): [.[].ports|join(\u0026#34;-\u0026#34;)]|unique }] | add\u0026#39; Which Services am I using? # aws ce get-cost-and-usage --time-period Start=2019-08-01,End=2019-08-31 --granularity MONTHLY --metrics UsageQuantity --group-by Type=DIMENSION,Key=SERVICE | jq \u0026#39;.ResultsByTime[].Groups[] | select(.Metrics.UsageQuantity.Amount \u0026gt; 0) | .Keys[0]\u0026#39; # How much they cost aws ce get-cost-and-usage --time-period Start=2019-08-01,End=2019-08-31 --granularity MONTHLY --metrics USAGE_QUANTITY BLENDED_COST --group-by Type=DIMENSION,Key=SERVICE | jq \u0026#39;[ .ResultsByTime[].Groups[] | select(.Metrics.BlendedCost.Amount \u0026gt; \u0026#34;0\u0026#34;) | { (.Keys[0]): .Metrics.BlendedCost } ] | sort_by(.Amount) | add\u0026#39; # Instances running aws ec2 describe-instances | jq -r \u0026#34;[[.Reservations[].Instances[]|{ state: .State.Name, type: .InstanceType }]|group_by(.state)|.[]|{state: .[0].state, types: [.[].type]|[group_by(.)|.[]|{type: .[0], count: ([.[]]|length)}] }]\u0026#34; CIDR access to ports # aws ec2 describe-security-groups | jq \u0026#39;[ .SecurityGroups[].IpPermissions[] as $a | { \u0026#34;ports\u0026#34;: [($a.FromPort|tostring),($a.ToPort|tostring)]|unique, \u0026#34;cidr\u0026#34;: $a.IpRanges[].CidrIp } ] | [group_by(.cidr)[] | { (.[0].cidr): [.[].ports|join(\u0026#34;-\u0026#34;)]|unique }] | add\u0026#39; Lambda runtimes # aws lambda list-functions | jq \u0026#34;.Functions | group_by(.Runtime)|[.[]|{ runtime:.[0].Runtime, functions:[.[]|.FunctionName] } ]\u0026#34; Memory size # aws lambda list-functions | jq \u0026#34;.Functions | group_by(.Runtime)|[.[]|{ (.[0].Runtime): [.[]|{ name: .FunctionName, timeout: .Timeout, memory: .MemorySize }] }]\u0026#34; Lambda Environment variables # aws lambda list-functions | jq -r \u0026#39;[.Functions[]|{name: .FunctionName, env: .Environment.Variables}]|.[]|select(.env|length \u0026gt; 0)\u0026#39; ","date":"October 3, 2019","externalUrl":null,"permalink":"/posts/2019-10-03-aws-inspection/","section":"Posts","summary":"Bunch of one-liners for AWS # .. so that I find them faster next time\naws --output=json ec2 describe-instances | jq -r '.Reservations[].Instances[] | \"\\n\" + .InstanceId + \" : \" + .KeyName + \" =\u003e \" + .PublicIpAddress + \" | \" + .PublicDnsName, .Tags[] as $tt | \" ... \" + $tt.Key +\":\"+ $tt.Value' aws ec2 describe-instances | jq '.Reservations[].Instances[] | .InstanceId + \" : \" + .Placement.AvailabilityZone + \" =\u003e \" + .PublicIpAddress' aws iam list-group-policies --group-name kops aws ec2 describe-vpcs | jq '.Vpcs[] | .VpcId + \" \" + .CidrBlock' aws iam list-users | jq '.Users[].UserName' aws --output=json --region=ca-central-1 ec2 describe-vpcs | jq -r '.Vpcs[] | .VpcId + \" \" + .CidrBlock,.Tags[] as $tt | \" .. \" + $tt.Key +\":\"+$tt.Value' aws ec2 describe-vpcs | jq -e --raw-output '.Vpcs[] | \"\\n\" + .VpcId + \" : \" + .CidrBlock, .Tags[] as $tt | \" ... \" + $tt.Key +\":\"+ $tt.Value' aws ec2 describe-subnets | jq -e --raw-output '.Subnets[] | \"\\n\" + .VpcId + \" : \" + .CidrBlock +\" : \" + .AvailabilityZone, .Tags[] as $tt | \" ... \" + $tt.Key +\":\"+ $tt.Value' aws ec2 authorize-security-group-ingress --group-id sg-bfa45bd4 --protocol tcp --port 31672 --cidr 204.101.219.210/31 How many instances of each type do I have, and in what states? # Considering buying reserved instances or thinking about migrating to a newly introduced class? aws ec2 describe-instances | jq -r \"[[.Reservations[].Instances[]|{ state: .State.Name, type: .InstanceType }]|group_by(.state)|.[]|{state: .[0].state, types: [.[].type]|[group_by(.)|.[]|{type: .[0], count: ([.[]]|length)}] }]\" What CIDRs have Ingress Access to which Ports? # # This is helpful when you need to perform a survey or audit of your system boundaries. While such a task isn’t ever “easy”, it can go more smoothly with with a summary: aws ec2 describe-security-groups | jq '[ .SecurityGroups[].IpPermissions[] as $a | { \"ports\": [($a.FromPort|tostring),($a.ToPort|tostring)]|unique, \"cidr\": $a.IpRanges[].CidrIp } ] | [group_by(.cidr)[] | { (.[0].cidr): [.[].ports|join(\"-\")]|unique }] | add' Which Services am I using? # aws ce get-cost-and-usage --time-period Start=2019-08-01,End=2019-08-31 --granularity MONTHLY --metrics UsageQuantity --group-by Type=DIMENSION,Key=SERVICE | jq '.ResultsByTime[].Groups[] | select(.Metrics.UsageQuantity.Amount \u003e 0) | .Keys[0]' # How much they cost aws ce get-cost-and-usage --time-period Start=2019-08-01,End=2019-08-31 --granularity MONTHLY --metrics USAGE_QUANTITY BLENDED_COST --group-by Type=DIMENSION,Key=SERVICE | jq '[ .ResultsByTime[].Groups[] | select(.Metrics.BlendedCost.Amount \u003e \"0\") | { (.Keys[0]): .Metrics.BlendedCost } ] | sort_by(.Amount) | add' # Instances running aws ec2 describe-instances | jq -r \"[[.Reservations[].Instances[]|{ state: .State.Name, type: .InstanceType }]|group_by(.state)|.[]|{state: .[0].state, types: [.[].type]|[group_by(.)|.[]|{type: .[0], count: ([.[]]|length)}] }]\" CIDR access to ports # aws ec2 describe-security-groups | jq '[ .SecurityGroups[].IpPermissions[] as $a | { \"ports\": [($a.FromPort|tostring),($a.ToPort|tostring)]|unique, \"cidr\": $a.IpRanges[].CidrIp } ] | [group_by(.cidr)[] | { (.[0].cidr): [.[].ports|join(\"-\")]|unique }] | add' Lambda runtimes # aws lambda list-functions | jq \".Functions | group_by(.Runtime)|[.[]|{ runtime:.[0].Runtime, functions:[.[]|.FunctionName] } ]\" Memory size # aws lambda list-functions | jq \".Functions | group_by(.Runtime)|[.[]|{ (.[0].Runtime): [.[]|{ name: .FunctionName, timeout: .Timeout, memory: .MemorySize }] }]\" Lambda Environment variables # aws lambda list-functions | jq -r '[.Functions[]|{name: .FunctionName, env: .Environment.Variables}]|.[]|select(.env|length \u003e 0)'","title":"AWS Inspection","type":"post"},{"content":"","date":"October 3, 2019","externalUrl":null,"permalink":"/tags/oneliners/","section":"Tags","summary":"","title":"Oneliners","type":"tags"},{"content":"Finally, we got to visit the mountains in the North - Pyrenees.\nSpecifically this place: https://benasque.com/en\nShort version # I liked it. Great hikes, very good food. Excellent hotel\nLong version # ","date":"September 29, 2019","externalUrl":null,"permalink":"/posts/2019-09-29-pyrenees/","section":"Posts","summary":"Finally, we got to visit the mountains in the North - Pyrenees.\nSpecifically this place: https://benasque.com/en\nShort version # I liked it. Great hikes, very good food. Excellent hotel\nLong version # ","title":"Pyrenees","type":"post"},{"content":"","date":"September 29, 2019","externalUrl":null,"permalink":"/tags/travel/","section":"Tags","summary":"","title":"Travel","type":"tags"},{"content":"","date":"September 12, 2019","externalUrl":null,"permalink":"/categories/jokes/","section":"Categories","summary":"","title":"Jokes","type":"categories"},{"content":"","date":"September 12, 2019","externalUrl":null,"permalink":"/tags/spanish/","section":"Tags","summary":"","title":"Spanish","type":"tags"},{"content":"The current weather in Valencia summed up: https://www.youtube.com/watch?v=j2VHUP7R2CY\nNote for my friends who think Catalan is more or less same as Spanish: go for it and translate :-)\n","date":"September 12, 2019","externalUrl":null,"permalink":"/posts/2019-09-12-post/","section":"Posts","summary":"The current weather in Valencia summed up: https://www.youtube.com/watch?v=j2VHUP7R2CY\nNote for my friends who think Catalan is more or less same as Spanish: go for it and translate :-)\n","title":"Spanish and Catalan","type":"post"},{"content":" ","date":"September 3, 2019","externalUrl":null,"permalink":"/posts/2019-09-03-bloom/","section":"Posts","summary":"","title":"Welcome back present","type":"post"},{"content":"Cafe and books. \u0026rsquo;nough said \u0026hellip;\n","date":"August 29, 2019","externalUrl":null,"permalink":"/posts/2019-08-29-post/","section":"Posts","summary":"Cafe and books. ’nough said …\n","title":"Cafe Eleven","type":"post"},{"content":"","date":"August 29, 2019","externalUrl":null,"permalink":"/tags/slovakia/","section":"Tags","summary":"","title":"Slovakia","type":"tags"},{"content":"I discovered this place rather late - at the end of my vacations.\nMaybe it was better so, otherwise I would my vacation here :-)\nhttps://spectator.sme.sk/c/22160317/bookworms-get-a-sanctuary-in-the-slovak-national-gallery.html\nI\u0026rsquo;ll be back !!!\n","date":"August 25, 2019","externalUrl":null,"permalink":"/posts/2019-08-25-foldvari/","section":"Posts","summary":"I discovered this place rather late - at the end of my vacations.\nMaybe it was better so, otherwise I would my vacation here :-)\nhttps://spectator.sme.sk/c/22160317/bookworms-get-a-sanctuary-in-the-slovak-national-gallery.html\nI’ll be back !!!\n","title":"Favorite places","type":"post"},{"content":"","date":"August 21, 2019","externalUrl":null,"permalink":"/tags/history/","section":"Tags","summary":"","title":"History","type":"tags"},{"content":"On 21 August 1968, the occupation army of Soviet Union with satelites invaded Czechoslovakia.\n","date":"August 21, 2019","externalUrl":null,"permalink":"/posts/2019-08-21-august/","section":"Posts","summary":"On 21 August 1968, the occupation army of Soviet Union with satelites invaded Czechoslovakia.\n","title":"Je me souviens","type":"post"},{"content":"After long time both we and both our children are in the same place.\nPrecious family time.\n","date":"August 3, 2019","externalUrl":null,"permalink":"/posts/2019-08-03-post/","section":"Posts","summary":"After long time both we and both our children are in the same place.\nPrecious family time.\n","title":"Family vacation","type":"post"},{"content":"Lost and then found again - here:https://angrytouristblog.blogspot.com/2015/10/rejoice-finland-man-is-back.html\nHere is the copy, just in case\nRejoice! The Finland Män is back! # Source\nFinland Män Not Like Smalltalk. Is Horror.\nFinland Män not kän underständ smalltalk. When kuud silense, samwan open mouth, silense destroid, why do tis?\nOne time Finland Män ko tu bar. Finland Män sit ät kounter, entshoi trink, look onli mopile phone. Is kuud silense. Then kam womän nekst tu Finland Män. She äsk: “Do you kam hiör often?” Finland Män pärälised. Is horror. Why she äsk tis? Is häv tu reäkt samhau? Finland Män luuk onli mopile phone. Tsek emails. Kiip luuking mopile phone. Then änssör: “Why you äsk? Is you kondukting sam sörvey?” Womän not say enitink. She ko öwei. Is kuud silense.\nFinland Män not kän underständ smalltalk. Rememper eksämppel of Krändfather. When Krändfather kam päk from thö war, he say: “Soviet Union vin.” Nekst time Krändfather open mouth in Kristmös 1991. Krändfather wotsh televishön njews. Krändfather say: “Nau Soviet Union luus.”\nOne time Finland Män ko tu restorant pikos hunkry. Finland Män sit ät teipul, entshoi moose, luuk onli mopile phone. Is kuud silense. Then kam waitter nekst tu Finland Män. He äsk: “Is everitink okei?” Finland Män pärälised. Is horror. Why he äsk tis? Is häv tu reäkt samhau? Finland Män luuk onli mopile phone. Tsek emails. Kiip luuking mopile phone. Then änssör: “Not is everitink okei. Ekonomi is proplem. Näshiönal produkt not krow.” Waitter not say enitink. He ko öwei. Is kuud silense.\n**Finland Män not kän **underständ smalltalk. Wörds is like karbon dioksid. Everipadi tudei put polluusshön in air. Is klimate tsheintsh.\nOne time Finland Män trävel in träm. Finland Män sit ölone, luuk onli mopile phone, is kuud silense. Then Ämerikan turist män say loud: “Wonderful weather you have here!” Finland Män pärälised. Is horror. Ämerikan turist män talk tu him. Why he say this? Is häv tu reäkt samhau? Finland Män luuk onli mopile phone. Tsek emails. Kiip luuking mopile phone. Then änssör: “It will ket wörse.” Finland Män ket out of träm. Wait for next tram, hopefuli no turist. Is kuud silense.\nThey häv safe distans. Is no smalltalk.\nWritten by Antti Hämäläinen Originally posted here.\n","date":"July 16, 2019","externalUrl":null,"permalink":"/posts/2019-07-18-finland-man/","section":"Posts","summary":"Lost and then found again - here:https://angrytouristblog.blogspot.com/2015/10/rejoice-finland-man-is-back.html\nHere is the copy, just in case\nRejoice! The Finland Män is back! # Source\nFinland Män Not Like Smalltalk. Is Horror.\nFinland Män not kän underständ smalltalk. When kuud silense, samwan open mouth, silense destroid, why do tis?\nOne time Finland Män ko tu bar. Finland Män sit ät kounter, entshoi trink, look onli mopile phone. Is kuud silense. Then kam womän nekst tu Finland Män. She äsk: “Do you kam hiör often?” Finland Män pärälised. Is horror. Why she äsk tis? Is häv tu reäkt samhau? Finland Män luuk onli mopile phone. Tsek emails. Kiip luuking mopile phone. Then änssör: “Why you äsk? Is you kondukting sam sörvey?” Womän not say enitink. She ko öwei. Is kuud silense.\n","title":"Finland Män","type":"post"},{"content":"with great paella.\n","date":"July 6, 2019","externalUrl":null,"permalink":"/posts/2019-07-06-picnic/","section":"Posts","summary":"with great paella.\n","title":"Company picnic","type":"post"},{"content":"I have my doubts whether it will survive. It is next to Starbucks (one of several, albeit nothing like Toronto) so there is competition for tourists looking for the familiar logo.\nAs for locals, Spanish coffee culture is quite different, and if I am allowed to say so - Spanish coffee is both better AND less expensive as\nSo let\u0026rsquo;s hope Timbits will save the day. Who could resist deep fried sugary dough, eh ?\nFor more and pictures:\n","date":"June 23, 2019","externalUrl":null,"permalink":"/posts/2019-06-23-tim-hortons/","section":"Posts","summary":"I have my doubts whether it will survive. It is next to Starbucks (one of several, albeit nothing like Toronto) so there is competition for tourists looking for the familiar logo.\nAs for locals, Spanish coffee culture is quite different, and if I am allowed to say so - Spanish coffee is both better AND less expensive as\nSo let’s hope Timbits will save the day. Who could resist deep fried sugary dough, eh ?\n","title":"Tim Hortons in Valencia","type":"post"},{"content":"","date":"May 26, 2019","externalUrl":null,"permalink":"/tags/canada/","section":"Tags","summary":"","title":"Canada","type":"tags"},{"content":"","date":"May 26, 2019","externalUrl":null,"permalink":"/tags/ottawa/","section":"Tags","summary":"","title":"Ottawa","type":"tags"},{"content":"I did quick 2 week visit to Canada.\nI spent some time with our son and daughter-in-law, visited many dear friends and places in the city and nature, worked for couple of days in the office and met new colleagues and even met current my boss for the first time in 3D. I must say, he is taller than in Zoom :-D\nI also visited our ex-cat with her new human servants and as expected, Lucy duly ignored me. Oh, well - cats.\nGabo gave me a ride in Tesla and as weather cooperated, I could do a few walkabouts and even catch the Tulip Festival with Peter.\nIt was great to be back.\nHere are some pictures:\n","date":"May 26, 2019","externalUrl":null,"permalink":"/posts/2019-05-25-ottawa/","section":"Posts","summary":"I did quick 2 week visit to Canada.\nI spent some time with our son and daughter-in-law, visited many dear friends and places in the city and nature, worked for couple of days in the office and met new colleagues and even met current my boss for the first time in 3D. I must say, he is taller than in Zoom :-D\nI also visited our ex-cat with her new human servants and as expected, Lucy duly ignored me. Oh, well - cats.\n","title":"Visit in Canada","type":"post"},{"content":"One day round trip Valencia to Madrid and back.\nIt is 350 km, but AVE (high velocity train) makes it in 1.5 hr. Take that, Via Rail !!\nTravelling at 300 km/h is unreal. It is actually quieter and more smooth than Canadian train at 80 - all that makes the speed believable is the velocity display and view out of the window when train goes around something closer to the rails.\nThe summit itself - very well organized, good content, great opportunity to practice Spanish. Lots of new ideas and material to process.\nSome pictures:\n","date":"May 7, 2019","externalUrl":null,"permalink":"/posts/2019-05-07-aws-summit/","section":"Posts","summary":"One day round trip Valencia to Madrid and back.\nIt is 350 km, but AVE (high velocity train) makes it in 1.5 hr. Take that, Via Rail !!\nTravelling at 300 km/h is unreal. It is actually quieter and more smooth than Canadian train at 80 - all that makes the speed believable is the velocity display and view out of the window when train goes around something closer to the rails.\n","title":"AWS Summit Madrid","type":"post"},{"content":"","date":"May 7, 2019","externalUrl":null,"permalink":"/tags/madrid/","section":"Tags","summary":"","title":"Madrid","type":"tags"},{"content":"","date":"May 7, 2019","externalUrl":null,"permalink":"/tags/summit/","section":"Tags","summary":"","title":"Summit","type":"tags"},{"content":"","date":"March 16, 2019","externalUrl":null,"permalink":"/tags/bash/","section":"Tags","summary":"","title":"Bash","type":"tags"},{"content":"","date":"March 16, 2019","externalUrl":null,"permalink":"/tags/jupyter/","section":"Tags","summary":"","title":"Jupyter","type":"tags"},{"content":" Adding Bash to Tensorflow notebook # I commented out PHP and C++ stuff that I do not really need:\nFROM jupyter/tensorflow-notebook USER root # install dependencies RUN apt-get update \u0026amp;\u0026amp; apt-get install -yq --no-install-recommends \\ php-cli php-dev php-pear \\ pkg-config \\ \u0026amp;\u0026amp; apt-get clean # rm -rf /var/lib/apt/lists/* # install zeromq and zmq php extension #RUN wget https://github.com/zeromq/zeromq4-1/releases/download/v4.1.5/zeromq-4.1.5.tar.gz \u0026amp;\u0026amp; \\ # tar -xvf zeromq-4.1.5.tar.gz \u0026amp;\u0026amp; \\ # cd zeromq-* \u0026amp;\u0026amp; \\ # ./configure \u0026amp;\u0026amp; make \u0026amp;\u0026amp; make install \u0026amp;\u0026amp; \\ # printf \u0026#34;\\n\u0026#34; | pecl install zmq-beta \u0026amp;\u0026amp; \\ # echo \u0026#34;extension=zmq.so\u0026#34; \u0026gt; /etc/php/7.0/cli/conf.d/zmq.ini # install PHP composer #RUN wget https://getcomposer.org/installer -O composer-setup.php \u0026amp;\u0026amp; \\ # wget https://litipk.github.io/Jupyter-PHP-Installer/dist/jupyter-php-installer.phar \u0026amp;\u0026amp; \\ # php composer-setup.php \u0026amp;\u0026amp; \\ # php ./jupyter-php-installer.phar -vvv install \u0026amp;\u0026amp; \\ # mv composer.phar /usr/local/bin/composer \u0026amp;\u0026amp; \\ # rm -rf zeromq-* jupyter-php* \u0026amp;\u0026amp; \\ # rm composer-setup.php # install ijavascript #RUN apt-get install -yq nodejs npm libzmq3-dev node-gyp \u0026amp;\u0026amp; \\ # npm install -g ijavascript \u0026amp;\u0026amp; \\ # ijs --ijs-install=global #RUN cd .. \u0026amp;\u0026amp; \\ # apt-get install -yq --no-install-recommends cmake \u0026amp;\u0026amp; \\ # wget https://raw.githubusercontent.com/root-mirror/cling/master/tools/packaging/cpt.py \u0026amp;\u0026amp; \\ # chmod +x cpt.py \u0026amp;\u0026amp; \\ # ./cpt.py --check-requirements \u0026amp;\u0026amp; ./cpt.py --create-dev-env Debug --with-workdir=./cling/ #RUN cd .. \u0026amp;\u0026amp; \\ # wget https://root.cern.ch/download/cling/cling_2017-09-15_ubuntu16.tar.bz2 \u0026amp;\u0026amp; \\ # tar -xvjf cling_2017-09-15_ubuntu16.tar.bz2 \u0026amp;\u0026amp; \\ # rm cling_*.tar.bz2 \u0026amp;\u0026amp; \\ # mv cling_* cling #RUN cd .. \u0026amp;\u0026amp; \\ # ln -s $(pwd)/cling/bin/* /usr/bin/ \u0026amp;\u0026amp; \\ # cd cling/share/cling/Jupyter/kernel \u0026amp;\u0026amp; \\ # pip install -e . \u0026amp;\u0026amp; \\ # jupyter-kernelspec install cling-cpp17 \u0026amp;\u0026amp; \\ # jupyter-kernelspec install cling-cpp14 \u0026amp;\u0026amp; \\ # jupyter-kernelspec install cling-cpp11 RUN chown -R $NB_USER /home/$NB_USER \u0026amp;\u0026amp; \\ rm -rf /home/$NB_USER/.local/share/jupyter # install java jre for h2o RUN apt-get install -yq openjdk-8-jre # Reset user from jupyter/base-notebook USER $NB_USER # install jupyter-bash RUN /opt/conda/bin/pip install --no-cache-dir bash_kernel RUN /opt/conda/bin/python -m bash_kernel.install # install h2o RUN /opt/conda/bin/pip install --no-cache-dir --upgrade h2o \u0026amp;\u0026amp; \\ /opt/conda/bin/pip install --no-cache-dir --upgrade pandas # disable authentication RUN mkdir -p .jupyter RUN echo \u0026#34;\u0026#34; \u0026gt;\u0026gt; ~/.jupyter/jupyter_notebook_config.py RUN echo \u0026#34;c.NotebookApp.token = \u0026#39;\u0026#39;\u0026#34; \u0026gt;\u0026gt; ~/.jupyter/jupyter_notebook_config.py Source: https://bitbucket.org/snippets/klassify/Ee9Myk/jupyter-notebook-with-bash-kernel\n","date":"March 16, 2019","externalUrl":null,"permalink":"/posts/2019-03-16-jupyter-bash/","section":"Posts","summary":"Adding Bash to Tensorflow notebook # I commented out PHP and C++ stuff that I do not really need:\nFROM jupyter/tensorflow-notebook USER root # install dependencies RUN apt-get update \u0026\u0026 apt-get install -yq --no-install-recommends \\ php-cli php-dev php-pear \\ pkg-config \\ \u0026\u0026 apt-get clean # rm -rf /var/lib/apt/lists/* # install zeromq and zmq php extension #RUN wget https://github.com/zeromq/zeromq4-1/releases/download/v4.1.5/zeromq-4.1.5.tar.gz \u0026\u0026 \\ # tar -xvf zeromq-4.1.5.tar.gz \u0026\u0026 \\ # cd zeromq-* \u0026\u0026 \\ # ./configure \u0026\u0026 make \u0026\u0026 make install \u0026\u0026 \\ # printf \"\\n\" | pecl install zmq-beta \u0026\u0026 \\ # echo \"extension=zmq.so\" \u003e /etc/php/7.0/cli/conf.d/zmq.ini # install PHP composer #RUN wget https://getcomposer.org/installer -O composer-setup.php \u0026\u0026 \\ # wget https://litipk.github.io/Jupyter-PHP-Installer/dist/jupyter-php-installer.phar \u0026\u0026 \\ # php composer-setup.php \u0026\u0026 \\ # php ./jupyter-php-installer.phar -vvv install \u0026\u0026 \\ # mv composer.phar /usr/local/bin/composer \u0026\u0026 \\ # rm -rf zeromq-* jupyter-php* \u0026\u0026 \\ # rm composer-setup.php # install ijavascript #RUN apt-get install -yq nodejs npm libzmq3-dev node-gyp \u0026\u0026 \\ # npm install -g ijavascript \u0026\u0026 \\ # ijs --ijs-install=global #RUN cd .. \u0026\u0026 \\ # apt-get install -yq --no-install-recommends cmake \u0026\u0026 \\ # wget https://raw.githubusercontent.com/root-mirror/cling/master/tools/packaging/cpt.py \u0026\u0026 \\ # chmod +x cpt.py \u0026\u0026 \\ # ./cpt.py --check-requirements \u0026\u0026 ./cpt.py --create-dev-env Debug --with-workdir=./cling/ #RUN cd .. \u0026\u0026 \\ # wget https://root.cern.ch/download/cling/cling_2017-09-15_ubuntu16.tar.bz2 \u0026\u0026 \\ # tar -xvjf cling_2017-09-15_ubuntu16.tar.bz2 \u0026\u0026 \\ # rm cling_*.tar.bz2 \u0026\u0026 \\ # mv cling_* cling #RUN cd .. \u0026\u0026 \\ # ln -s $(pwd)/cling/bin/* /usr/bin/ \u0026\u0026 \\ # cd cling/share/cling/Jupyter/kernel \u0026\u0026 \\ # pip install -e . \u0026\u0026 \\ # jupyter-kernelspec install cling-cpp17 \u0026\u0026 \\ # jupyter-kernelspec install cling-cpp14 \u0026\u0026 \\ # jupyter-kernelspec install cling-cpp11 RUN chown -R $NB_USER /home/$NB_USER \u0026\u0026 \\ rm -rf /home/$NB_USER/.local/share/jupyter # install java jre for h2o RUN apt-get install -yq openjdk-8-jre # Reset user from jupyter/base-notebook USER $NB_USER # install jupyter-bash RUN /opt/conda/bin/pip install --no-cache-dir bash_kernel RUN /opt/conda/bin/python -m bash_kernel.install # install h2o RUN /opt/conda/bin/pip install --no-cache-dir --upgrade h2o \u0026\u0026 \\ /opt/conda/bin/pip install --no-cache-dir --upgrade pandas # disable authentication RUN mkdir -p .jupyter RUN echo \"\" \u003e\u003e ~/.jupyter/jupyter_notebook_config.py RUN echo \"c.NotebookApp.token = ''\" \u003e\u003e ~/.jupyter/jupyter_notebook_config.py Source: https://bitbucket.org/snippets/klassify/Ee9Myk/jupyter-notebook-with-bash-kernel\n","title":"Jupyter notebook with Bash kernel","type":"post"},{"content":"","date":"March 16, 2019","externalUrl":null,"permalink":"/categories/programming/","section":"Categories","summary":"","title":"Programming","type":"categories"},{"content":"","date":"February 10, 2019","externalUrl":null,"permalink":"/tags/java/","section":"Tags","summary":"","title":"Java","type":"tags"},{"content":"","date":"February 10, 2019","externalUrl":null,"permalink":"/tags/ssl/","section":"Tags","summary":"","title":"Ssl","type":"tags"},{"content":" Cybersource Testing Tool # Java utility that we used before when we were debugging the TLS 1.2 issues.\nIt needs to be compiled with JDK 1.8 - ideally the same one that runs in production and then run like:\njava -Djavax.net.debug=ssl:handshake:verbose SSLPoke api.cybersource.com 443 replace api.cybersource.com with whatever the cybersource endpoint needs to be.\nIf the utility responds with \u0026lsquo;Successfully connected’, it was able to handshake with the SSL server and establish the secure connection.\njavac SSLPoke java -Djavax.net.debug=ssl:handshake:verbose SSLPoke api.cybersource.com 443 Snippet: https://bitbucket.org/snippets/thinkwrap/5j656n/sslpoke\n","date":"February 10, 2019","externalUrl":null,"permalink":"/posts/2019-02-10-ssl-poke/","section":"Posts","summary":"Cybersource Testing Tool # Java utility that we used before when we were debugging the TLS 1.2 issues.\nIt needs to be compiled with JDK 1.8 - ideally the same one that runs in production and then run like:\njava -Djavax.net.debug=ssl:handshake:verbose SSLPoke api.cybersource.com 443 replace api.cybersource.com with whatever the cybersource endpoint needs to be.\nIf the utility responds with ‘Successfully connected’, it was able to handshake with the SSL server and establish the secure connection.\n","title":"SSL Poke","type":"post"},{"content":"Two small utilities I have places into ~/bin:\ngit-attic # Source: https://github.com/maximeh/dotfiles/blob/master/common/.bin/git-attic\n#!/bin/sh # git-attic [-M] [PATH] - list deleted files of Git repositories # # Use -M to not show renamed files, and other git-log options as you like. git log --raw --no-renames --date=short --format=\u0026#34;%h %cd\u0026#34; \u0026#34;$@\u0026#34; | awk \u0026#39;/^[0-9a-f]/ { commit=$1; date=$2 } /^:/ \u0026amp;\u0026amp; $5 == \u0026#34;D\u0026#34; { print date, commit \u0026#34;^:\u0026#34; $6 }\u0026#39; | less Example # ➜ kubernetes-the-hard-way git:(master) ✗ git log --raw --no-renames --date=short --format=\u0026#34;%h %cd\u0026#34; \u0026#34;$@\u0026#34; | awk \u0026#39;/^[0-9a-f]/ { commit=$1; date=$2 } /^:/ \u0026amp;\u0026amp; $5 == \u0026#34;D\u0026#34; { print date, commit \u0026#34;^:\u0026#34; $6 }\u0026#39; 2019-11-20 374e8d9^:docs/using-rst/pdp-template-rst.rst 2019-11-17 7911114^:src/certificates/admin-csr.json 2019-11-17 7911114^:src/certificates/admin-key.pem 2019-11-17 7911114^:src/certificates/admin.csr 2019-11-17 7911114^:src/certificates/admin.pem 2019-11-17 7911114^:src/certificates/ca-config.json 2019-11-17 7911114^:src/certificates/ca-csr.json 2019-11-17 7911114^:src/certificates/ca-key.pem 2019-11-17 7911114^:src/certificates/ca.csr 2019-11-17 7911114^:src/certificates/ca.pem 2019-11-17 7911114^:src/certificates/copy-certificates-to-servers.sh git trail # I cannot remember where is this one from :-(\n#!/bin/sh -e # git trail [-r] [-t] [COMMIT] - show all branching points in Git history [ \u0026#34;$1\u0026#34; = -r ] \u0026amp;\u0026amp; shift || REMOTES=\u0026#34;-e refs/remotes/\u0026#34; [ \u0026#34;$1\u0026#34; = -t ] \u0026amp;\u0026amp; shift || TAGS=\u0026#34;-e refs/tags/\u0026#34; COMMIT=$(git rev-parse --no-flags --default HEAD \u0026#34;$@\u0026#34;) { git for-each-ref | grep -v -e \u0026#39;^$\u0026#39; $TAGS $REMOTES git log --date=short --format=\u0026#34;%cd %h %H\u0026#34; \u0026#34;$@\u0026#34; } | awk \u0026#39; $2 == \u0026#34;commit\u0026#34; || $2 == \u0026#34;tag\u0026#34; { \u0026#34;git merge-base \u0026#39;$COMMIT\u0026#39; \u0026#34; $1 | getline mb merge[mb] = merge[mb] \u0026#34; \u0026#34; $3 } { if ($3 in merge) { split(merge[$3], mbs, \u0026#34; \u0026#34;) for (i in mbs) { \u0026#34;git name-rev --name-only --refs=\\\u0026#34;\u0026#34; mbs[i] \u0026#34;\\\u0026#34; \u0026#34; $3 | getline nr if (nr != \u0026#34;undefined\u0026#34;) print $1, $2, nr # skip unreachable commits } } ","date":"January 14, 2019","externalUrl":null,"permalink":"/posts/2019-01-14-gitbits/","section":"Posts","summary":"Two small utilities I have places into ~/bin:\ngit-attic # Source: https://github.com/maximeh/dotfiles/blob/master/common/.bin/git-attic\n#!/bin/sh # git-attic [-M] [PATH] - list deleted files of Git repositories # # Use -M to not show renamed files, and other git-log options as you like. git log --raw --no-renames --date=short --format=\"%h %cd\" \"$@\" | awk '/^[0-9a-f]/ { commit=$1; date=$2 } /^:/ \u0026\u0026 $5 == \"D\" { print date, commit \"^:\" $6 }' | less Example # ➜ kubernetes-the-hard-way git:(master) ✗ git log --raw --no-renames --date=short --format=\"%h %cd\" \"$@\" | awk '/^[0-9a-f]/ { commit=$1; date=$2 } /^:/ \u0026\u0026 $5 == \"D\" { print date, commit \"^:\" $6 }' 2019-11-20 374e8d9^:docs/using-rst/pdp-template-rst.rst 2019-11-17 7911114^:src/certificates/admin-csr.json 2019-11-17 7911114^:src/certificates/admin-key.pem 2019-11-17 7911114^:src/certificates/admin.csr 2019-11-17 7911114^:src/certificates/admin.pem 2019-11-17 7911114^:src/certificates/ca-config.json 2019-11-17 7911114^:src/certificates/ca-csr.json 2019-11-17 7911114^:src/certificates/ca-key.pem 2019-11-17 7911114^:src/certificates/ca.csr 2019-11-17 7911114^:src/certificates/ca.pem 2019-11-17 7911114^:src/certificates/copy-certificates-to-servers.sh git trail # I cannot remember where is this one from :-(\n","title":"Gitbits","type":"post"},{"content":"","date":"January 14, 2019","externalUrl":null,"permalink":"/tags/tools/","section":"Tags","summary":"","title":"Tools","type":"tags"},{"content":"I have just returned from DockerCon Europe 2018 and I’d like to share my impressions while they are fresh in my mind. It was my first DockerCon so I was not quite sure what to expect. As the title says, it was great experience and barring the scaling issue (more below) could have been really awesome experience.\nBut let\u0026rsquo;s take things in order. First location - Barcelona. Hard to pick better place in December than Spain. I am sure the Northerners greatly appreciated the break from cold and enjoyed the balmy 15 to 20 degrees. The venue Centre de Convencions Internacional de Barcelona - CCIB - though not located in the centre, is at the shore and one can walk to the beach in 2-3 minutes. There were three of us going from Valencia office (which is 3 hours train ride down the coast from Barcelona) and we had also great hotel experience. I can highly recommend Hotel Princess Barcelona. What can be better than starting your day with watching sunrise over Mediterranean Sea. Thanks David - because you did such a great job, you are now in charge of travel and hotel booking going forward :-D\nThe registration was well prepared and smooth. Considering the amount of participants (I do not have the numbers, but it felt well over thousand) it was very quick. DockerCon mobile app was available with up to date schedule, agenda, speakers info and feedback option and it worked quite well.\nContent # The activities of the DockerCon come in different form, targeting different audiences and different sized rooms.\nThere were general sessions aka keynotes - the only ones streamed online (see DockerCon). These were in big hall seating everybody. From my point of view, these were OK but not overly exciting. What I heard only confirms impression about direction of the Docker as a company - but I will get back to that.\nMuch more interesting were Breakout sessions and Community theatre sessions. Breakout sessions were hosted on first floor in auditoriums of capacity hundreds of participants. There were multiple tracks focusing on developers, operations etc - 5 in total and we had to choose one. Sometimes two interesting tracks overlapped, but judging by the presence of the recording crew, those I missed will be eventually available as recordings. Cannot wait until I can add them to my long watch list - still working through AWS re:Invent 2018 videos.\nPretty much every session I attended was good or great. It was very interesting to see Jaana B. Dogan of Google (@rakyll) in person (you may know the name if you are following GoLang space or Medium. Here are the [slides])https://speakerdeck.com/rakyll/monitoring-and-debugging-containers)\nThe few I would like to emphasize are those where I either learned something new or I can immediately use it - e.g. \u0026ldquo;Dockerfile Best Practices\u0026rdquo; by Sebastiaan van Stijn and Tibor Vass, or \u0026ldquo;Tips and Tricks of the Docker Captains\u0026rdquo;\nThe nice surprise at the DockerCon was for me the presentation of Sean Gillespie of Pulumi: Program the Cloud Using Containers as the Building Block. At first sight the idea looked a lot like Trophoshere in Typescript - use real programming language in place of DSL or YAML, only instead of being limited to Python and generation of Cloudformation, one can use TypeScript, Python or Go and instead of only script generation it interfaces with target API on your behalf. The target API can be AWS, GCP or Azure - or Kubernetes. And it also maintains state (inside their cloud for now, more backends coming). So all in all - this is like Terraform with real programming language instead of HCL - something that may come very handy. I am intrigued and will certainly try it out. It is open source and this is the repo and https://github.com/pulumi/pulumi. Btw - great presentation, Sean - it was pleasure to listen to you.\nIn Community theatre - interesting talk about psychology of doing code reviews by Elodie Rafalimanana and for me personally very interesting “Transparent Execution of Scientific Workflows in Docker Containers” from Barcelona Supercomputing Centre” by Jorge Ejarque and talk by Boston Consulting Group on “Lessons in Using Docker to Close the Loop on Industrializing AI and ML Applications” (Clement Roche and Bartlomiej Nogas). The talk “Improving Docker Desktop File Sharing Performance” by David Scott and Pierre Gayvallet was also very useful for practical day-to-day work.\nAs on every conference, there were some product announcements and important innovations. Some were on Enterprise side - Docker Desktop Enterprise, which may be important for the Docker penetration of the large enterprises and new features of DockerEE. I personally found most interesting convergence of docker-compose and Kubernetes file formats and \u0026ldquo;default\u0026rdquo; Kubernetes local cluster available in Docker since version 18.09. The addition (and opening up) of the buildkit with possibility of adding new syntax to Docker file is something that will have great impact and allow innovation in many directions. Generally, the improvements in buildkit were pretty impressive and examples shown with multi-container builds made me gasp few times. Well done, Docker team and Docker community.\nOne important announcement about which I have mixed feelings was docker assemble - new tool that allows creating docker image without creation of Dockerfile. Sure it is useful, but did not make me anywhere as impressed as the improvements above. Dockerfiles are not exactly rocket science and saving creation of boilerplate ones for common scenarios like Java Maven project or DotNet project is not such a great help - IMHO. I may be wrong but somehow it does not seem to be such a big deal.\nDocker sees it as very important though, and it was emphasized in the keynote that the strategic goal is to move from ~ 1 mil of users (mostly Linux) to 10+ millions and include many more Windows users. Importance of Windows, making things simpler and emphasis on Enterprise and enterprise customers were the main corporate theme here in Barcelona. I think there is an acquisition writing on the wall and Microsoft is the buyer. It would make a lot of sense for both - and frankly, Microsoft would be IMHO better option than some the other names mentioned (hello Oracle). All recent events point in that direction - the departure of the co-founder and CTO in May and new CTO - an enterprise veteran from WMWare and Oracle Kal De.\nThe other important announcement confirming the importance of Windows and Microsoft was CNAB - cloud native application bundle\nI guess, with the exponential growth Docker is experiencing, the \u0026ldquo;enterprisation\u0026rdquo; is inevitable and morphing of the small, loved, open-source company into something playing in the big leagues is observed with mixed feelings. Luckily, the Docker community and ecosystem is awesome, stronger than ever and will not make it easy for greed to stifle the technical innovation. The strong community will prevail - there are enough good recent examples that show this - like Java and raise of OpenJDK (hello Oracle again).\nThere were lots of booths and vendor demos. I liked the SysDig and the Datadog demos. We had nice chat with Rancher team and I even found ex-paesano from Czech republic in RedHat booth (one can always recognize the homeland accent). I also had good opportunity to dust off my German.\nThe AWS was present, pushing Fargate (no surprise there) as well as Azure. It is great that somebody is trying to compete with Amazon. Google did not have any booth, neither did any of the \u0026ldquo;lesser clouds\u0026rdquo;.\nThe food at the event was great, by far the best of any conference I went to. Jose (being used to very high standard as a Spaniard) said it was OK - but he was comparing with Barcelona and Valencia \u0026ldquo;native level\u0026rdquo; of expectations. For us, guiris it was just great. Well - except the coffee which was OK. Or maybe I am getting get used to \u0026ldquo;native level\u0026rdquo; ? LOL.\nDockerCon Party # On day two Docker threw very impressive party. The busses took us from conference centre to the night club district at the shore - Barcelonetta - where people could choose among 4 different styles of clubs: salsa / cuban music, electronic lounge, jazz themed and Indian / Asian themed with what may have been authentic live Indian music. All 4 clubs were interconnected by the shared beach so one could walk on the beach and visit all of them. Add very good food and open bar and you\u0026rsquo;ll have complete picture. Night clubs with lots of people are not exactly my natural habitat, so it was interesting to see it for a change. Now I can say I was in a night club in Spain. Actually, on Tuesday I probably visited more night clubs than during previous 40 years :-).\nThe fly in the ointment # Now we are coming to the \u0026ldquo;fly in the ointment\u0026rdquo; of the conference - the workshops. The organizers decided to host one of the most interesting parts of the conference - workshops - in small rooms seating tens of people. The rational probably being to keep the hands-on spirit of the presentation, make communication and interaction feasible - which makes sense. As a teacher and trainer I understand very well that it is hard to do deeper hands-on sessions with larger audiencies. What was IMHO complete and inexcusable failure on the side of organizers was\ncommunication of real capacity and expectation management lack of providing \u0026ldquo;read-only\u0026rdquo; access via streaming to overflow rooms failure to record the sessions. Actually, a combination of 1 and (2 or 3) would had solved the problem.\nThere was mentioning on the website of the DockerCon that RSVP for workshops is required. I tried to register the week before the conference and every workshop was allready full, including the waiting list. On Monday - first day of the conference - there were only workshops scheduled, all of them unavailable.\nAs we found out, there were hundreds of people in the same situation, and even those who tried to register weeks before the event did not get in. This was mentioned on the discussion in the conference app several times. So it was clear to organizers weeks ahead that the capacity of the sessions is way under the expected demand and they did absolutely nothing.\nThe communication and expectation management was IMHO pretty misleading: the conference web site should had explained that \u0026ldquo;Workshops: RSVP required\u0026rdquo; on the website page describing what was included in the conference offering actually meant this: \u0026ldquo;some 20 % of you conference pass buyers may get chance to get into workshop sessions if you are really fast and we will do nothing for the rest of you - just happily take your money\u0026rdquo;.\nConsidering that one day out of three the only scheduled sessions were workshops (the breakouts, general sessions and Community Theatre was only on Tue and Wed) all big breakout rooms were empty on Monday and there were enough of them to broadcast the stream of each of the workshops - all that was required was to do it. Not good enough, Docker !\nSome people went for Self-paced hands-on - which may had been nice alternative for beginners with Docker or people interested in Docker Enterprise. Not belonging to either of those groups, we went to Barcelona center and spent 3 hours walking through the one of the most interesting and beautiful cities in Europe. Which was kinda silver lining on the Monday.\nConclusion # But let bygones be bygones and focus on the positive: I am very happy I went.\nI feel energized and inspired, have discovered few completely new things to try, got many useful hints on how to improve workflows and tools I use, saw the marvellous creations of Gaudi and sunrise over the sea again, spent time with friends among people of my tribe, and even got to the high end nightclub - what a great 3 days. The clear unspoken message from both the breakout sessions, announcements and demos was importance and dominance of Kubernetes, new raising Cloud OS.\nWhich - btw - does not really need Docker and can run using different containerization technologies. But that is a different story.\n","date":"December 7, 2018","externalUrl":null,"permalink":"/posts/2018-12-07-dockercon-2018/","section":"Posts","summary":"I have just returned from DockerCon Europe 2018 and I’d like to share my impressions while they are fresh in my mind. It was my first DockerCon so I was not quite sure what to expect. As the title says, it was great experience and barring the scaling issue (more below) could have been really awesome experience.\nBut let’s take things in order. First location - Barcelona. Hard to pick better place in December than Spain. I am sure the Northerners greatly appreciated the break from cold and enjoyed the balmy 15 to 20 degrees. The venue Centre de Convencions Internacional de Barcelona - CCIB - though not located in the centre, is at the shore and one can walk to the beach in 2-3 minutes. There were three of us going from Valencia office (which is 3 hours train ride down the coast from Barcelona) and we had also great hotel experience. I can highly recommend Hotel Princess Barcelona. What can be better than starting your day with watching sunrise over Mediterranean Sea. Thanks David - because you did such a great job, you are now in charge of travel and hotel booking going forward :-D\n","title":"DockerCon 2018 - great event (with a small fly in the ointment)","type":"post"},{"content":"Got the second certification today\nhttps://www.certmetrics.com/amazon/public/badge.aspx?i=2\u0026t=c\u0026d=2018-11-28\u0026ci=AWS00261816\n","date":"October 28, 2018","externalUrl":null,"permalink":"/posts/2018-11-28-aws/","section":"Posts","summary":"Got the second certification today\nhttps://www.certmetrics.com/amazon/public/badge.aspx?i=2\u0026t=c\u0026d=2018-11-28\u0026ci=AWS00261816\n","title":"AWS Certified Developer - Associate","type":"post"},{"content":" Czechoslovakia would be 100 today # 1918-10-28 - 1992-12-31 # We (both nations) we lucky to separate paths the peaceful way and at the end of the day, both countries are in the EU, NATO and relations between Czechs and Slovak are probably the best ever because the quarrels over budget and transfers ended.\nIt is a bit nostalgic though, admitting that we were the last naturally bilingual generation that could read a book and a week later not to be 100% sure whether it was in Czech or in Slovak.\n","date":"October 28, 2018","externalUrl":null,"permalink":"/posts/2018-11-17-panpan/","section":"Posts","summary":"Czechoslovakia would be 100 today # 1918-10-28 - 1992-12-31 # We (both nations) we lucky to separate paths the peaceful way and at the end of the day, both countries are in the EU, NATO and relations between Czechs and Slovak are probably the best ever because the quarrels over budget and transfers ended.\n","title":"Happy birthday Czechoslovakia","type":"post"},{"content":"","date":"October 24, 2018","externalUrl":null,"permalink":"/tags/commandline/","section":"Tags","summary":"","title":"Commandline","type":"tags"},{"content":" Skopeo # I have stumbled upon this tool: https://github.com/containers/skopeo - command line tools for manipulation with Docker images and Docker image registries.\nIt can work with OCI images as well as the original Docker v2 images.\nInstallation # brew install skopeo Usage # ➜ deploy-2018-10-24 skopeo --override-os=linux inspect docker://docker.io/fedora { \u0026#34;Name\u0026#34;: \u0026#34;docker.io/library/fedora\u0026#34;, \u0026#34;Digest\u0026#34;: \u0026#34;sha256:b41cd083421dd7aa46d619e958b75a026a5d5733f08f14ba6d53943d6106ea6d\u0026#34;, \u0026#34;RepoTags\u0026#34;: [ \u0026#34;20\u0026#34;, \u0026#34;21\u0026#34;, \u0026#34;22\u0026#34;, \u0026#34;23\u0026#34;, \u0026#34;24\u0026#34;, \u0026#34;25\u0026#34;, \u0026#34;26-modular\u0026#34;, \u0026#34;26\u0026#34;, \u0026#34;27\u0026#34;, \u0026#34;28\u0026#34;, \u0026#34;29\u0026#34;, \u0026#34;branched\u0026#34;, \u0026#34;heisenbug\u0026#34;, \u0026#34;latest\u0026#34;, \u0026#34;modular\u0026#34;, \u0026#34;rawhide\u0026#34; ], \u0026#34;Created\u0026#34;: \u0026#34;2018-09-07T19:20:02.809176076Z\u0026#34;, \u0026#34;DockerVersion\u0026#34;: \u0026#34;17.06.2-ce\u0026#34;, \u0026#34;Labels\u0026#34;: null, \u0026#34;Architecture\u0026#34;: \u0026#34;amd64\u0026#34;, \u0026#34;Os\u0026#34;: \u0026#34;linux\u0026#34;, \u0026#34;Layers\u0026#34;: [ \u0026#34;sha256:565884f490d9ec697e519c57d55d09e268542ef2c1340fd63262751fa308f047\u0026#34; ] } It works with protected repos as well - as long as creds are provided\nskopeo --override-os=linux inspect --creds=\u0026#39;\u0026#39;${CREDS}\u0026#39;\u0026#39; docker://docker.io/thinkwrap/dropship-ui:uat | jq \u0026#34;.Digest\u0026#34; \u0026#34;sha256:43f95207dafa7dbc034e5126a9f6b6952e47e162206e889c1071f6e06308f4f4\u0026#34; The reason for override-os is running the client on MacOS. On Linux, this can be removed.\nThe double single quotes around ${CREDS} is to make sure that special characters in password such as ;!| will not confuse shell.\nGetting information about all Tags # skopeo --override-os=linux inspect --creds=\u0026#39;\u0026#39;${CREDS}\u0026#39;\u0026#39; docker://docker.io/thinkwrap/dropship-ui:uat | jq \u0026#34;.RepoTags[]\u0026#34; \u0026#34;0.3.0\u0026#34; \u0026#34;1.3.0-uat\u0026#34; \u0026#34;1.3.1-uat\u0026#34; \u0026#34;1.3.2-uat\u0026#34; \u0026#34;1.4.0-uat\u0026#34; \u0026#34;1.4.1-uat\u0026#34; \u0026#34;1.4.2-uat\u0026#34; \u0026#34;1.4.3-uat\u0026#34; \u0026#34;1.4.4-uat\u0026#34; \u0026#34;1.4.5-uat\u0026#34; \u0026#34;1.4.6-uat\u0026#34; \u0026#34;1.5.0-uat\u0026#34; \u0026#34;1.5.1-uat\u0026#34; \u0026#34;1.5.2-uat\u0026#34; \u0026#34;1.5.3-uat\u0026#34; \u0026#34;1.5.4-uat\u0026#34; \u0026#34;1.5.5-uat\u0026#34; \u0026#34;1.5.6-uat\u0026#34; \u0026#34;development\u0026#34; \u0026#34;uat\u0026#34; Speaking of Docker container tools, see also: https://github.com/GoogleContainerTools/container-diff\n","date":"October 24, 2018","externalUrl":null,"permalink":"/posts/2018-10-24-dockerhub-tool/","section":"Posts","summary":"Skopeo # I have stumbled upon this tool: https://github.com/containers/skopeo - command line tools for manipulation with Docker images and Docker image registries.\nIt can work with OCI images as well as the original Docker v2 images.\nInstallation # brew install skopeo Usage # ➜ deploy-2018-10-24 skopeo --override-os=linux inspect docker://docker.io/fedora { \"Name\": \"docker.io/library/fedora\", \"Digest\": \"sha256:b41cd083421dd7aa46d619e958b75a026a5d5733f08f14ba6d53943d6106ea6d\", \"RepoTags\": [ \"20\", \"21\", \"22\", \"23\", \"24\", \"25\", \"26-modular\", \"26\", \"27\", \"28\", \"29\", \"branched\", \"heisenbug\", \"latest\", \"modular\", \"rawhide\" ], \"Created\": \"2018-09-07T19:20:02.809176076Z\", \"DockerVersion\": \"17.06.2-ce\", \"Labels\": null, \"Architecture\": \"amd64\", \"Os\": \"linux\", \"Layers\": [ \"sha256:565884f490d9ec697e519c57d55d09e268542ef2c1340fd63262751fa308f047\" ] } It works with protected repos as well - as long as creds are provided\n","title":"Useful tool for Dockerhub","type":"post"},{"content":"","date":"October 23, 2018","externalUrl":null,"permalink":"/tags/google/","section":"Tags","summary":"","title":"Google","type":"tags"},{"content":"Installed Google Wifi - three access points. Finally I have good coverage on both floors of the appartment including the upper terrace and will be able to work at night outside during hot summer nights when temperature does not drop under 25.\nThe setup was supereasy and iOS app is very well made and gives interesting insights.\nHappy.\n","date":"October 23, 2018","externalUrl":null,"permalink":"/posts/2018-10-23-google-wifi/","section":"Posts","summary":"Installed Google Wifi - three access points. Finally I have good coverage on both floors of the appartment including the upper terrace and will be able to work at night outside during hot summer nights when temperature does not drop under 25.\nThe setup was supereasy and iOS app is very well made and gives interesting insights.\nHappy.\n","title":"Google Wifi","type":"post"},{"content":"","date":"October 23, 2018","externalUrl":null,"permalink":"/tags/hardware/","section":"Tags","summary":"","title":"Hardware","type":"tags"},{"content":"It\u0026rsquo;s been five years since I started toying with idea to learn first romance language in my collection - despite living in Canada for over 18 years, I never picked up French.\nThe learning was slow during 2014 and 2015 (just summer school in Spain and Duolingo) - but it accelerated a lot in last 2 years.\nFast forward to now: on Sunday while watching Prime (https://en.wikipedia.org/wiki/Prime_(film)) we have decided to switch from English to Spanish (with Spanish subtitles) to enjoy the movie better than in original.\nMisión (casi) cumplida :-)\nNunca es demasiado tarde para comenzar algo nuevo.\n","date":"October 2, 2018","externalUrl":null,"permalink":"/posts/2018-10-02-spanish/","section":"Posts","summary":"It’s been five years since I started toying with idea to learn first romance language in my collection - despite living in Canada for over 18 years, I never picked up French.\nThe learning was slow during 2014 and 2015 (just summer school in Spain and Duolingo) - but it accelerated a lot in last 2 years.\nFast forward to now: on Sunday while watching Prime (https://en.wikipedia.org/wiki/Prime_(film)) we have decided to switch from English to Spanish (with Spanish subtitles) to enjoy the movie better than in original.\n","title":"Mission (almost) accomplished","type":"post"},{"content":"","date":"September 6, 2018","externalUrl":null,"permalink":"/tags/events/","section":"Tags","summary":"","title":"Events","type":"tags"},{"content":"I took 3 days off and decided to explore the North of Spain, namely Cantabria and Asturias.\nIt was awesome and beautiful. Asturias reminded me of Switzerland, with beautiful alpine style nature, great food, very friendly locals speaking language one can understand :-) (I kinda do understand certain versions of Schwyzzertütsch when spoken slowly - but it is a challenge).\nUnlike Switzerland, it is not überexpensive.\nHere are the pictures.\n","date":"September 6, 2018","externalUrl":null,"permalink":"/posts/2018-09-15-road-trip/","section":"Posts","summary":"I took 3 days off and decided to explore the North of Spain, namely Cantabria and Asturias.\nIt was awesome and beautiful. Asturias reminded me of Switzerland, with beautiful alpine style nature, great food, very friendly locals speaking language one can understand :-) (I kinda do understand certain versions of Schwyzzertütsch when spoken slowly - but it is a challenge).\nUnlike Switzerland, it is not überexpensive.\nHere are the pictures.\n","title":"Road Trip","type":"post"},{"content":"One of the Microsoft old-timer bilionaries, Charles Simonyi, Hungarian born software engineer, famous for his Hungarian naming notation - who would not remember lpstrzDescription or wFlag - is visiting Valencia on his yacht Skat.\nThose who do not write code (or better said - did not write code 20 years ago) may be familiar with his other contribution - Microsoft Word, something I feel much less positive about than lpstrzDescription.\nhttps://www.lasprovincias.es/valencia-ciudad/megayate-guerra-microsoft-word-20180906191209-nt.html\nHe is also 2x space tourist - see https://en.wikipedia.org/wiki/Charles_Simonyi\n","date":"September 6, 2018","externalUrl":null,"permalink":"/posts/2018-09-06-simonyi/","section":"Posts","summary":"One of the Microsoft old-timer bilionaries, Charles Simonyi, Hungarian born software engineer, famous for his Hungarian naming notation - who would not remember lpstrzDescription or wFlag - is visiting Valencia on his yacht Skat.\nThose who do not write code (or better said - did not write code 20 years ago) may be familiar with his other contribution - Microsoft Word, something I feel much less positive about than lpstrzDescription.\n","title":"Simonyi Karoly in Valencia","type":"post"},{"content":" ","date":"July 31, 2018","externalUrl":null,"permalink":"/posts/2018-07-31-spanish/","section":"Posts","summary":" ","title":"This made my day","type":"post"},{"content":"If one uses Oracle per core licensing strategy in cloud:\n","date":"June 25, 2018","externalUrl":null,"permalink":"/posts/2018-06-25-oracle/","section":"Posts","summary":"If one uses Oracle per core licensing strategy in cloud:\n","title":"Per core licensing","type":"post"},{"content":"Step 1 done.\nhttps://www.certmetrics.com/amazon/public/badge.aspx?i=1\u0026t=c\u0026d=2018-06-06\u0026ci=AWS00261816\u0026fbclid=IwAR2K8B4FyKWVstBZXCXn5GhYX9iRyB4U2q8l2ROrM_16m-rlclioalnp0O4\nAnd now dilemma: go deeper into AWS or look around what Google and Azure have to offer ?\nSo many clouds, so little time \u0026hellip;\n","date":"June 7, 2018","externalUrl":null,"permalink":"/posts/2018-06-07-aws/","section":"Posts","summary":"Step 1 done.\nhttps://www.certmetrics.com/amazon/public/badge.aspx?i=1\u0026t=c\u0026d=2018-06-06\u0026ci=AWS00261816\u0026fbclid=IwAR2K8B4FyKWVstBZXCXn5GhYX9iRyB4U2q8l2ROrM_16m-rlclioalnp0O4\nAnd now dilemma: go deeper into AWS or look around what Google and Azure have to offer ?\nSo many clouds, so little time …\n","title":"AWS Certified Solution Architect - Associate","type":"post"},{"content":"Fellow Canadian describes his path to Spain\nhttps://tapasforever.com/\n","date":"June 7, 2018","externalUrl":null,"permalink":"/posts/2018-06-03-botd/","section":"Posts","summary":"Fellow Canadian describes his path to Spain\nhttps://tapasforever.com/\n","title":"Blog of the day - Tapas Forever","type":"post"},{"content":"This describes creation of K8s cluster in AWS environment from scratch as done for microservices based eCommerce project.\nPre-requisites # AWS account access - IAM with Admin privileges AWS CLI installed - https://docs.aws.amazon.com/cli/latest/userguide/cli-install-macos.html CLI credentials (secret key + api Key) - https://docs.aws.amazon.com/cli/latest/reference/iam/index.html Kubectl and Kops local install ** see https://github.com/kubernetes/kops and https://kubernetes.io/docs/tasks/tools/install-kubectl/ Test of access # ➜ etc git:(feature/kubernetes) aws --version aws-cli/1.11.180 Python/3.6.4 Darwin/17.5.0 botocore/1.7.38 ➜ etc git:(feature/kubernetes) kubectl version Client Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;10\u0026#34;, GitVersion:\u0026#34;v1.10.1\u0026#34;, GitCommit:\u0026#34;d4ab47518836c750f9949b9e0d387f20fb92260b\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2018-04-13T22:27:55Z\u0026#34;, GoVersion:\u0026#34;go1.9.5\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;darwin/amd64\u0026#34;} Server Version: version.Info{Major:\u0026#34;1\u0026#34;, Minor:\u0026#34;9\u0026#34;, GitVersion:\u0026#34;v1.9.3\u0026#34;, GitCommit:\u0026#34;d2835416544f298c919e2ead3be3d0864b52323b\u0026#34;, GitTreeState:\u0026#34;clean\u0026#34;, BuildDate:\u0026#34;2018-02-07T11:55:20Z\u0026#34;, GoVersion:\u0026#34;go1.9.2\u0026#34;, Compiler:\u0026#34;gc\u0026#34;, Platform:\u0026#34;linux/amd64\u0026#34;} ➜ etc git:(feature/kubernetes) kops version Version 1.9.0 ➜ etc git:(feature/kubernetes) aws --profile twfulfill-miro iam list-users | jq \u0026#39;.Users[].UserName\u0026#39; .. DELETED ... \u0026#34;twfulfillment.prod.miro.adamy\u0026#34; .... Set the environment variables # These will be used by subsequent kops / aws commands\n➜ etc git:(feature/kubernetes) export AWS_ACCESS_KEY_ID=\u0026lt;YOUR-ACCESS-KEY\u0026gt; ➜ etc git:(feature/kubernetes) export AWS_SECRET_ACCESS_KEY=\u0026lt;YOUR-SECRET-KEY\u0026gt; ## Optional - if using ~/.aws/config + ~/.aws/credentials ➜ etc git:(feature/kubernetes) export AWS_PROFILE=twfulfill-miro ## Validate ➜ etc git:(feature/kubernetes) env | grep AWS_ AWS_ACCESS_KEY_ID=..... AWS_SECRET_ACCESS_KEY=S..................t AWS_PROFILE=twfulfill-miro Create kops IAM group + attach policies # ➜ etc git:(feature/kubernetes) aws iam create-group --group-name kops { \u0026#34;Group\u0026#34;: { \u0026#34;Path\u0026#34;: \u0026#34;/\u0026#34;, \u0026#34;GroupName\u0026#34;: \u0026#34;kops\u0026#34;, \u0026#34;GroupId\u0026#34;: \u0026#34;AGPAJWJNXBDYEPXP3VTJW\u0026#34;, \u0026#34;Arn\u0026#34;: \u0026#34;arn:aws:iam::125911927208:group/kops\u0026#34;, \u0026#34;CreateDate\u0026#34;: \u0026#34;2018-05-07T15:13:38.493Z\u0026#34; } } ➜ etc git:(feature/kubernetes) aws iam list-group-policies --group-name kops { \u0026#34;PolicyNames\u0026#34;: [] } ➜ etc git:(feature/kubernetes) aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops ➜ etc git:(feature/kubernetes) aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops ➜ etc git:(feature/kubernetes) aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops ➜ etc git:(feature/kubernetes) aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops ➜ etc git:(feature/kubernetes) aws iam list-attached-group-policies --group-name kops { \u0026#34;AttachedPolicies\u0026#34;: [ { \u0026#34;PolicyName\u0026#34;: \u0026#34;AmazonEC2FullAccess\u0026#34;, \u0026#34;PolicyArn\u0026#34;: \u0026#34;arn:aws:iam::aws:policy/AmazonEC2FullAccess\u0026#34; }, { \u0026#34;PolicyName\u0026#34;: \u0026#34;IAMFullAccess\u0026#34;, \u0026#34;PolicyArn\u0026#34;: \u0026#34;arn:aws:iam::aws:policy/IAMFullAccess\u0026#34; }, { \u0026#34;PolicyName\u0026#34;: \u0026#34;AmazonS3FullAccess\u0026#34;, \u0026#34;PolicyArn\u0026#34;: \u0026#34;arn:aws:iam::aws:policy/AmazonS3FullAccess\u0026#34; }, { \u0026#34;PolicyName\u0026#34;: \u0026#34;AmazonVPCFullAccess\u0026#34;, \u0026#34;PolicyArn\u0026#34;: \u0026#34;arn:aws:iam::aws:policy/AmazonVPCFullAccess\u0026#34; }, { \u0026#34;PolicyName\u0026#34;: \u0026#34;AmazonRoute53FullAccess\u0026#34;, \u0026#34;PolicyArn\u0026#34;: \u0026#34;arn:aws:iam::aws:policy/AmazonRoute53FullAccess\u0026#34; } ] } ## However - list of group policies is still empty (== explicit policies) ➜ etc git:(feature/kubernetes) aws iam list-group-policies --group-name kops { \u0026#34;PolicyNames\u0026#34;: [] } Create kops user # ## Before ➜ etc git:(feature/kubernetes) aws iam list-users | jq \u0026#34;.Users[].UserName\u0026#34; \u0026#34;twfulfillment.prod.miro.adamy\u0026#34; ... DELETED ... # Create kops user ➜ etc git:(feature/kubernetes) aws iam create-user --user-name kops { \u0026#34;User\u0026#34;: { \u0026#34;Path\u0026#34;: \u0026#34;/\u0026#34;, \u0026#34;UserName\u0026#34;: \u0026#34;kops\u0026#34;, \u0026#34;UserId\u0026#34;: \u0026#34;AIDAJHZVKEPICOZOMHNHK\u0026#34;, \u0026#34;Arn\u0026#34;: \u0026#34;arn:aws:iam::125911927208:user/kops\u0026#34;, \u0026#34;CreateDate\u0026#34;: \u0026#34;2018-05-07T15:22:05.574Z\u0026#34; } } ## Check if created ➜ etc git:(feature/kubernetes) aws iam list-users | jq \u0026#34;.Users[].UserName\u0026#34; \u0026#34;kops\u0026#34; \u0026#34;twfulfillment.prod.miro.adamy\u0026#34; ... DELETED ... ## Add to the group ➜ etc git:(feature/kubernetes) aws iam add-user-to-group --user-name kops --group-name kops ## Verify adding to the group ➜ etc git:(feature/kubernetes) aws iam list-groups-for-user --user-name kops { \u0026#34;Groups\u0026#34;: [ { \u0026#34;Path\u0026#34;: \u0026#34;/\u0026#34;, \u0026#34;GroupName\u0026#34;: \u0026#34;kops\u0026#34;, \u0026#34;GroupId\u0026#34;: \u0026#34;AGPAJWJNXBDYEPXP3VTJW\u0026#34;, \u0026#34;Arn\u0026#34;: \u0026#34;arn:aws:iam::125911927208:group/kops\u0026#34;, \u0026#34;CreateDate\u0026#34;: \u0026#34;2018-05-07T15:13:38Z\u0026#34; } ] } S3 Buckets # Kops needs dedicated S3 bucket to store artifacts.\nWe will create one for each environment now: DEV, UAT, PROD.\nNaming convention: PROJECT-k8s-ENVIRONMENT\n## List existing buckets ➜ etc git:(feature/kubernetes) aws s3api list-buckets { \u0026#34;Buckets\u0026#34;: [], \u0026#34;Owner\u0026#34;: { \u0026#34;DisplayName\u0026#34;: \u0026#34;twfulfillment.aws\u0026#34;, \u0026#34;ID\u0026#34;: \u0026#34;f4d3f1f61cb382de98ebf5b7d58306b66ad6108cdd1916cdd3cce94e88aeeb47\u0026#34; } } ## For buckets not in us-east-1 we need location constraint ➜ etc git:(feature/kubernetes) aws s3api create-bucket --bucket twfulfillment-k8s-uat --region us-east-1 { \u0026#34;Location\u0026#34;: \u0026#34;/twfulfillment-k8s-uat\u0026#34; } ➜ etc git:(feature/kubernetes) aws s3api create-bucket --bucket twfulfillment-k8s-dev --region us-east-1 { \u0026#34;Location\u0026#34;: \u0026#34;/twfulfillment-k8s-dev\u0026#34; } ➜ etc git:(feature/kubernetes) aws s3api create-bucket --bucket twfulfillment-k8s-prod --region us-east-2 --create-bucket-configuration LocationConstraint=us-east-2 { \u0026#34;Location\u0026#34;: \u0026#34;http://twfulfillment-k8s-prod.s3.amazonaws.com/\u0026#34; } ➜ etc git:(feature/kubernetes) aws s3api list-buckets { \u0026#34;Buckets\u0026#34;: [ { \u0026#34;Name\u0026#34;: \u0026#34;twfulfillment-k8s-dev\u0026#34;, \u0026#34;CreationDate\u0026#34;: \u0026#34;2018-05-07T15:34:10.000Z\u0026#34; }, { \u0026#34;Name\u0026#34;: \u0026#34;twfulfillment-k8s-prod\u0026#34;, \u0026#34;CreationDate\u0026#34;: \u0026#34;2018-05-07T15:34:29.000Z\u0026#34; }, { \u0026#34;Name\u0026#34;: \u0026#34;twfulfillment-k8s-uat\u0026#34;, \u0026#34;CreationDate\u0026#34;: \u0026#34;2018-05-07T15:33:55.000Z\u0026#34; } ], \u0026#34;Owner\u0026#34;: { \u0026#34;DisplayName\u0026#34;: \u0026#34;twfulfillment.aws\u0026#34;, \u0026#34;ID\u0026#34;: \u0026#34;f4d3f1f61cb382de98ebf5b7d58306b66ad6108cdd1916cdd3cce94e88aeeb47\u0026#34; } } ## Enable versioning on all 3 ➜ etc git:(feature/kubernetes) aws s3api put-bucket-versioning --bucket twfulfillment-k8s-prod --versioning-configuration Status=Enabled ➜ etc git:(feature/kubernetes) aws s3api put-bucket-versioning --bucket twfulfillment-k8s-uat --versioning-configuration Status=Enabled ➜ etc git:(feature/kubernetes) aws s3api put-bucket-versioning --bucket twfulfillment-k8s-dev --versioning-configuration Status=Enabled ## ... and verify ➜ etc git:(feature/kubernetes) aws s3api get-bucket-versioning --bucket twfulfillment-k8s-dev { \u0026#34;Status\u0026#34;: \u0026#34;Enabled\u0026#34; } ➜ etc git:(feature/kubernetes) aws s3api get-bucket-versioning --bucket twfulfillment-k8s-uat { \u0026#34;Status\u0026#34;: \u0026#34;Enabled\u0026#34; } ➜ etc git:(feature/kubernetes) aws s3api get-bucket-versioning --bucket twfulfillment-k8s-prod { \u0026#34;Status\u0026#34;: \u0026#34;Enabled\u0026#34; } Set up cluster using kops # From now on, make SURE the AWS_xxx env variables are defined.\nGenerate key pairs\n➜ etc git:(feature/kubernetes) cd k8s ➜ k8s git:(feature/kubernetes) ll ## Location of keys for DEV and UAT. See ➜ k8s git:(feature/kubernetes) pwd /Users/miro/src/TWC/fragrm-integ/etc/k8s ## ssh-keygen -t rsa -C twfulfillment-dev-ssh ssh-keygen -t rsa -C twfulfillment-uat-ssh ssh-keygen -t rsa -C twfulfillment-prod-ssh ## Check the keys ➜ k8s git:(feature/kubernetes) ✗ ll total 48 -rw------- 1 miro staff 1.6K 7 May 17:42 twfulfillment-dev-ssh -rw-r--r-- 1 miro staff 403B 7 May 17:42 twfulfillment-dev-ssh.pub -rw------- 1 miro staff 1.6K 7 May 17:42 twfulfillment-prod-ssh -rw-r--r-- 1 miro staff 404B 7 May 17:42 twfulfillment-prod-ssh.pub -rw------- 1 miro staff 1.6K 7 May 17:42 twfulfillment-uat-ssh -rw-r--r-- 1 miro staff 403B 7 May 17:42 twfulfillment-uat-ssh.pub Creating the clusters # We will be creating 2 clusters in us-east-1\nThe instances used will be 3x t2.medium per cluster - 1x master + 2 worker nodes. We need t2.medium for Java processes and Kuberneters recommends the master to be at least t2.medium (or t2.large for larger number of worker nodes).\nThe command\nkops create cluster --zones us-east-1a,us-east-1b --name twfulfillment-uat.k8s.local --ssh-public-key=./twfulfillment-uat-ssh.pub --state=s3://twfulfillment-k8s-uat --kubernetes-version 1.9.3 --node-count 2 --node-size t2.medium --master-size t2.medium Preview # ➜ k8s git:(feature/kubernetes) kops create cluster --zones us-east-1a,us-east-1b --name twfulfillment-uat.k8s.local --ssh-public-key=./twfulfillment-uat-ssh.pub --state=s3://twfulfillment-k8s-uat --kubernetes-version 1.9.3 --node-count 2 --node-size t2.medium --master-size t2.medium I0507 18:22:46.988689 59427 create_cluster.go:1318] Using SSH public key: ./twfulfillment-uat-ssh.pub I0507 18:22:48.416794 59427 create_cluster.go:472] Inferred --cloud=aws from zone \u0026#34;us-east-1a\u0026#34; I0507 18:22:49.245107 59427 subnets.go:184] Assigned CIDR 172.20.32.0/19 to subnet us-east-1a I0507 18:22:49.245129 59427 subnets.go:184] Assigned CIDR 172.20.64.0/19 to subnet us-east-1b Previewing changes that will be made: I0507 18:22:53.266660 59427 apply_cluster.go:456] Gossip DNS: skipping DNS validation I0507 18:22:53.284804 59427 executor.go:91] Tasks: 0 done / 79 total; 30 can run I0507 18:22:54.411940 59427 executor.go:91] Tasks: 30 done / 79 total; 25 can run I0507 18:22:55.653767 59427 executor.go:91] Tasks: 55 done / 79 total; 20 can run I0507 18:22:56.531068 59427 executor.go:91] Tasks: 75 done / 79 total; 3 can run W0507 18:22:56.663831 59427 keypair.go:140] Task did not have an address: *awstasks.LoadBalancer {\u0026#34;Name\u0026#34;:\u0026#34;api.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;LoadBalancerName\u0026#34;:\u0026#34;api-twfulfillment-uat-k8s-hqhbfl\u0026#34;,\u0026#34;DNSName\u0026#34;:null,\u0026#34;HostedZoneId\u0026#34;:null,\u0026#34;Subnets\u0026#34;:[{\u0026#34;Name\u0026#34;:\u0026#34;us-east-1a.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;VPC\u0026#34;:{\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;CIDR\u0026#34;:\u0026#34;172.20.0.0/16\u0026#34;,\u0026#34;AdditionalCIDR\u0026#34;:null,\u0026#34;EnableDNSHostnames\u0026#34;:true,\u0026#34;EnableDNSSupport\u0026#34;:true,\u0026#34;Shared\u0026#34;:false,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;}},\u0026#34;AvailabilityZone\u0026#34;:\u0026#34;us-east-1a\u0026#34;,\u0026#34;CIDR\u0026#34;:\u0026#34;172.20.32.0/19\u0026#34;,\u0026#34;Shared\u0026#34;:false,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;us-east-1a.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;SubnetType\u0026#34;:\u0026#34;Public\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;,\u0026#34;kubernetes.io/role/elb\u0026#34;:\u0026#34;1\u0026#34;}},{\u0026#34;Name\u0026#34;:\u0026#34;us-east-1b.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;VPC\u0026#34;:{\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;CIDR\u0026#34;:\u0026#34;172.20.0.0/16\u0026#34;,\u0026#34;AdditionalCIDR\u0026#34;:null,\u0026#34;EnableDNSHostnames\u0026#34;:true,\u0026#34;EnableDNSSupport\u0026#34;:true,\u0026#34;Shared\u0026#34;:false,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;}},\u0026#34;AvailabilityZone\u0026#34;:\u0026#34;us-east-1b\u0026#34;,\u0026#34;CIDR\u0026#34;:\u0026#34;172.20.64.0/19\u0026#34;,\u0026#34;Shared\u0026#34;:false,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;us-east-1b.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;SubnetType\u0026#34;:\u0026#34;Public\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;,\u0026#34;kubernetes.io/role/elb\u0026#34;:\u0026#34;1\u0026#34;}}],\u0026#34;SecurityGroups\u0026#34;:[{\u0026#34;Name\u0026#34;:\u0026#34;api-elb.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;Description\u0026#34;:\u0026#34;Security group for api ELB\u0026#34;,\u0026#34;VPC\u0026#34;:{\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Lifecycle\u0026#34;:\u0026#34;Sync\u0026#34;,\u0026#34;ID\u0026#34;:null,\u0026#34;CIDR\u0026#34;:\u0026#34;172.20.0.0/16\u0026#34;,\u0026#34;AdditionalCIDR\u0026#34;:null,\u0026#34;EnableDNSHostnames\u0026#34;:true,\u0026#34;EnableDNSSupport\u0026#34;:true,\u0026#34;Shared\u0026#34;:false,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;}},\u0026#34;RemoveExtraRules\u0026#34;:[\u0026#34;port=443\u0026#34;],\u0026#34;Shared\u0026#34;:null,\u0026#34;Tags\u0026#34;:{\u0026#34;KubernetesCluster\u0026#34;:\u0026#34;twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;Name\u0026#34;:\u0026#34;api-elb.twfulfillment-uat.k8s.local\u0026#34;,\u0026#34;kubernetes.io/cluster/twfulfillment-uat.k8s.local\u0026#34;:\u0026#34;owned\u0026#34;}}],\u0026#34;Listeners\u0026#34;:{\u0026#34;443\u0026#34;:{\u0026#34;InstancePort\u0026#34;:443}},\u0026#34;Scheme\u0026#34;:null,\u0026#34;HealthCheck\u0026#34;:{\u0026#34;Target\u0026#34;:\u0026#34;SSL:443\u0026#34;,\u0026#34;HealthyThreshold\u0026#34;:2,\u0026#34;UnhealthyThreshold\u0026#34;:2,\u0026#34;Interval\u0026#34;:10,\u0026#34;Timeout\u0026#34;:5},\u0026#34;AccessLog\u0026#34;:null,\u0026#34;ConnectionDraining\u0026#34;:null,\u0026#34;ConnectionSettings\u0026#34;:{\u0026#34;IdleTimeout\u0026#34;:300},\u0026#34;CrossZoneLoadBalancing\u0026#34;:null} I0507 18:22:57.252182 59427 executor.go:91] Tasks: 78 done / 79 total; 1 can run I0507 18:22:57.438067 59427 executor.go:91] Tasks: 79 done / 79 total; 0 can run Will create resources: AutoscalingGroup/master-us-east-1a.masters.twfulfillment-uat.k8s.local MinSize 1 MaxSize 1 Subnets [name:us-east-1a.twfulfillment-uat.k8s.local] Tags {k8s.io/role/master: 1, Name: master-us-east-1a.masters.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, k8s.io/cluster-autoscaler/node-template/label/kops.k8s.io/instancegroup: master-us-east-1a} Granularity 1Minute Metrics [GroupDesiredCapacity, GroupInServiceInstances, GroupMaxSize, GroupMinSize, GroupPendingInstances, GroupStandbyInstances, GroupTerminatingInstances, GroupTotalInstances] LaunchConfiguration name:master-us-east-1a.masters.twfulfillment-uat.k8s.local AutoscalingGroup/nodes.twfulfillment-uat.k8s.local MinSize 2 MaxSize 2 Subnets [name:us-east-1a.twfulfillment-uat.k8s.local, name:us-east-1b.twfulfillment-uat.k8s.local] Tags {Name: nodes.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, k8s.io/cluster-autoscaler/node-template/label/kops.k8s.io/instancegroup: nodes, k8s.io/role/node: 1} Granularity 1Minute Metrics [GroupDesiredCapacity, GroupInServiceInstances, GroupMaxSize, GroupMinSize, GroupPendingInstances, GroupStandbyInstances, GroupTerminatingInstances, GroupTotalInstances] LaunchConfiguration name:nodes.twfulfillment-uat.k8s.local DHCPOptions/twfulfillment-uat.k8s.local DomainName ec2.internal DomainNameServers AmazonProvidedDNS Shared false Tags {Name: twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} EBSVolume/a.etcd-events.twfulfillment-uat.k8s.local AvailabilityZone us-east-1a VolumeType gp2 SizeGB 20 Encrypted false Tags {k8s.io/etcd/events: a/a, k8s.io/role/master: 1, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned, Name: a.etcd-events.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local} EBSVolume/a.etcd-main.twfulfillment-uat.k8s.local AvailabilityZone us-east-1a VolumeType gp2 SizeGB 20 Encrypted false Tags {k8s.io/etcd/main: a/a, k8s.io/role/master: 1, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned, Name: a.etcd-main.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local} IAMInstanceProfile/masters.twfulfillment-uat.k8s.local IAMInstanceProfile/nodes.twfulfillment-uat.k8s.local IAMInstanceProfileRole/masters.twfulfillment-uat.k8s.local InstanceProfile name:masters.twfulfillment-uat.k8s.local id:masters.twfulfillment-uat.k8s.local Role name:masters.twfulfillment-uat.k8s.local IAMInstanceProfileRole/nodes.twfulfillment-uat.k8s.local InstanceProfile name:nodes.twfulfillment-uat.k8s.local id:nodes.twfulfillment-uat.k8s.local Role name:nodes.twfulfillment-uat.k8s.local IAMRole/masters.twfulfillment-uat.k8s.local ExportWithID masters IAMRole/nodes.twfulfillment-uat.k8s.local ExportWithID nodes IAMRolePolicy/masters.twfulfillment-uat.k8s.local Role name:masters.twfulfillment-uat.k8s.local IAMRolePolicy/nodes.twfulfillment-uat.k8s.local Role name:nodes.twfulfillment-uat.k8s.local InternetGateway/twfulfillment-uat.k8s.local VPC name:twfulfillment-uat.k8s.local Shared false Tags {Name: twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} Keypair/apiserver-aggregator Signer name:apiserver-aggregator-ca id:cn=apiserver-aggregator-ca Subject cn=aggregator Type client Format v1alpha2 Keypair/apiserver-aggregator-ca Subject cn=apiserver-aggregator-ca Type ca Format v1alpha2 Keypair/apiserver-proxy-client Signer name:ca id:cn=kubernetes Subject cn=apiserver-proxy-client Type client Format v1alpha2 Keypair/ca Subject cn=kubernetes Type ca Format v1alpha2 Keypair/kops Signer name:ca id:cn=kubernetes Subject o=system:masters,cn=kops Type client Format v1alpha2 Keypair/kube-controller-manager Signer name:ca id:cn=kubernetes Subject cn=system:kube-controller-manager Type client Format v1alpha2 Keypair/kube-proxy Signer name:ca id:cn=kubernetes Subject cn=system:kube-proxy Type client Format v1alpha2 Keypair/kube-scheduler Signer name:ca id:cn=kubernetes Subject cn=system:kube-scheduler Type client Format v1alpha2 Keypair/kubecfg Signer name:ca id:cn=kubernetes Subject o=system:masters,cn=kubecfg Type client Format v1alpha2 Keypair/kubelet Signer name:ca id:cn=kubernetes Subject o=system:nodes,cn=kubelet Type client Format v1alpha2 Keypair/kubelet-api Signer name:ca id:cn=kubernetes Subject cn=kubelet-api Type client Format v1alpha2 Keypair/master AlternateNames [100.64.0.1, 127.0.0.1, api.internal.twfulfillment-uat.k8s.local, api.twfulfillment-uat.k8s.local, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local] Signer name:ca id:cn=kubernetes Subject cn=kubernetes-master Type server Format v1alpha2 LaunchConfiguration/master-us-east-1a.masters.twfulfillment-uat.k8s.local ImageID kope.io/k8s-1.8-debian-jessie-amd64-hvm-ebs-2018-02-08 InstanceType t2.medium SSHKey name:kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 id:kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 SecurityGroups [name:masters.twfulfillment-uat.k8s.local] AssociatePublicIP true IAMInstanceProfile name:masters.twfulfillment-uat.k8s.local id:masters.twfulfillment-uat.k8s.local RootVolumeSize 64 RootVolumeType gp2 SpotPrice LaunchConfiguration/nodes.twfulfillment-uat.k8s.local ImageID kope.io/k8s-1.8-debian-jessie-amd64-hvm-ebs-2018-02-08 InstanceType t2.medium SSHKey name:kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 id:kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 SecurityGroups [name:nodes.twfulfillment-uat.k8s.local] AssociatePublicIP true IAMInstanceProfile name:nodes.twfulfillment-uat.k8s.local id:nodes.twfulfillment-uat.k8s.local RootVolumeSize 128 RootVolumeType gp2 SpotPrice LoadBalancer/api.twfulfillment-uat.k8s.local LoadBalancerName api-twfulfillment-uat-k8s-hqhbfl Subnets [name:us-east-1a.twfulfillment-uat.k8s.local, name:us-east-1b.twfulfillment-uat.k8s.local] SecurityGroups [name:api-elb.twfulfillment-uat.k8s.local] Listeners {443: {\u0026#34;InstancePort\u0026#34;:443}} HealthCheck {\u0026#34;Target\u0026#34;:\u0026#34;SSL:443\u0026#34;,\u0026#34;HealthyThreshold\u0026#34;:2,\u0026#34;UnhealthyThreshold\u0026#34;:2,\u0026#34;Interval\u0026#34;:10,\u0026#34;Timeout\u0026#34;:5} ConnectionSettings {\u0026#34;IdleTimeout\u0026#34;:300} LoadBalancerAttachment/api-master-us-east-1a LoadBalancer name:api.twfulfillment-uat.k8s.local id:api.twfulfillment-uat.k8s.local AutoscalingGroup name:master-us-east-1a.masters.twfulfillment-uat.k8s.local id:master-us-east-1a.masters.twfulfillment-uat.k8s.local ManagedFile/twfulfillment-uat.k8s.local-addons-bootstrap Location addons/bootstrap-channel.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-core.addons.k8s.io Location addons/core.addons.k8s.io/v1.4.0.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-dns-controller.addons.k8s.io-k8s-1.6 Location addons/dns-controller.addons.k8s.io/k8s-1.6.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-dns-controller.addons.k8s.io-pre-k8s-1.6 Location addons/dns-controller.addons.k8s.io/pre-k8s-1.6.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-kube-dns.addons.k8s.io-k8s-1.6 Location addons/kube-dns.addons.k8s.io/k8s-1.6.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-kube-dns.addons.k8s.io-pre-k8s-1.6 Location addons/kube-dns.addons.k8s.io/pre-k8s-1.6.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-limit-range.addons.k8s.io Location addons/limit-range.addons.k8s.io/v1.5.0.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-rbac.addons.k8s.io-k8s-1.8 Location addons/rbac.addons.k8s.io/k8s-1.8.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-storage-aws.addons.k8s.io-v1.6.0 Location addons/storage-aws.addons.k8s.io/v1.6.0.yaml ManagedFile/twfulfillment-uat.k8s.local-addons-storage-aws.addons.k8s.io-v1.7.0 Location addons/storage-aws.addons.k8s.io/v1.7.0.yaml Route/0.0.0.0/0 RouteTable name:twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 InternetGateway name:twfulfillment-uat.k8s.local RouteTable/twfulfillment-uat.k8s.local VPC name:twfulfillment-uat.k8s.local Shared false Tags {Name: twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned, kubernetes.io/kops/role: public} RouteTableAssociation/us-east-1a.twfulfillment-uat.k8s.local RouteTable name:twfulfillment-uat.k8s.local Subnet name:us-east-1a.twfulfillment-uat.k8s.local RouteTableAssociation/us-east-1b.twfulfillment-uat.k8s.local RouteTable name:twfulfillment-uat.k8s.local Subnet name:us-east-1b.twfulfillment-uat.k8s.local SSHKey/kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 KeyFingerprint 16:58:c0:9f:cd:99:22:53:72:95:4a:3b:85:1e:e1:28 Secret/admin Secret/kube Secret/kube-proxy Secret/kubelet Secret/system:controller_manager Secret/system:dns Secret/system:logging Secret/system:monitoring Secret/system:scheduler SecurityGroup/api-elb.twfulfillment-uat.k8s.local Description Security group for api ELB VPC name:twfulfillment-uat.k8s.local RemoveExtraRules [port=443] Tags {Name: api-elb.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} SecurityGroup/masters.twfulfillment-uat.k8s.local Description Security group for masters VPC name:twfulfillment-uat.k8s.local RemoveExtraRules [port=22, port=443, port=2380, port=2381, port=4001, port=4002, port=4789, port=179] Tags {Name: masters.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} SecurityGroup/nodes.twfulfillment-uat.k8s.local Description Security group for nodes VPC name:twfulfillment-uat.k8s.local RemoveExtraRules [port=22] Tags {Name: nodes.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} SecurityGroupRule/all-master-to-master SecurityGroup name:masters.twfulfillment-uat.k8s.local SourceGroup name:masters.twfulfillment-uat.k8s.local SecurityGroupRule/all-master-to-node SecurityGroup name:nodes.twfulfillment-uat.k8s.local SourceGroup name:masters.twfulfillment-uat.k8s.local SecurityGroupRule/all-node-to-node SecurityGroup name:nodes.twfulfillment-uat.k8s.local SourceGroup name:nodes.twfulfillment-uat.k8s.local SecurityGroupRule/api-elb-egress SecurityGroup name:api-elb.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Egress true SecurityGroupRule/https-api-elb-0.0.0.0/0 SecurityGroup name:api-elb.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Protocol tcp FromPort 443 ToPort 443 SecurityGroupRule/https-elb-to-master SecurityGroup name:masters.twfulfillment-uat.k8s.local Protocol tcp FromPort 443 ToPort 443 SourceGroup name:api-elb.twfulfillment-uat.k8s.local SecurityGroupRule/master-egress SecurityGroup name:masters.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Egress true SecurityGroupRule/node-egress SecurityGroup name:nodes.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Egress true SecurityGroupRule/node-to-master-tcp-1-2379 SecurityGroup name:masters.twfulfillment-uat.k8s.local Protocol tcp FromPort 1 ToPort 2379 SourceGroup name:nodes.twfulfillment-uat.k8s.local SecurityGroupRule/node-to-master-tcp-2382-4000 SecurityGroup name:masters.twfulfillment-uat.k8s.local Protocol tcp FromPort 2382 ToPort 4000 SourceGroup name:nodes.twfulfillment-uat.k8s.local SecurityGroupRule/node-to-master-tcp-4003-65535 SecurityGroup name:masters.twfulfillment-uat.k8s.local Protocol tcp FromPort 4003 ToPort 65535 SourceGroup name:nodes.twfulfillment-uat.k8s.local SecurityGroupRule/node-to-master-udp-1-65535 SecurityGroup name:masters.twfulfillment-uat.k8s.local Protocol udp FromPort 1 ToPort 65535 SourceGroup name:nodes.twfulfillment-uat.k8s.local SecurityGroupRule/ssh-external-to-master-0.0.0.0/0 SecurityGroup name:masters.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Protocol tcp FromPort 22 ToPort 22 SecurityGroupRule/ssh-external-to-node-0.0.0.0/0 SecurityGroup name:nodes.twfulfillment-uat.k8s.local CIDR 0.0.0.0/0 Protocol tcp FromPort 22 ToPort 22 Subnet/us-east-1a.twfulfillment-uat.k8s.local VPC name:twfulfillment-uat.k8s.local AvailabilityZone us-east-1a CIDR 172.20.32.0/19 Shared false Tags {Name: us-east-1a.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned, kubernetes.io/role/elb: 1, SubnetType: Public} Subnet/us-east-1b.twfulfillment-uat.k8s.local VPC name:twfulfillment-uat.k8s.local AvailabilityZone us-east-1b CIDR 172.20.64.0/19 Shared false Tags {Name: us-east-1b.twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned, kubernetes.io/role/elb: 1, SubnetType: Public} VPC/twfulfillment-uat.k8s.local CIDR 172.20.0.0/16 EnableDNSHostnames true EnableDNSSupport true Shared false Tags {Name: twfulfillment-uat.k8s.local, KubernetesCluster: twfulfillment-uat.k8s.local, kubernetes.io/cluster/twfulfillment-uat.k8s.local: owned} VPCDHCPOptionsAssociation/twfulfillment-uat.k8s.local VPC name:twfulfillment-uat.k8s.local DHCPOptions name:twfulfillment-uat.k8s.local Must specify --yes to apply changes Cluster configuration has been created. Suggestions: * list clusters with: kops get cluster * edit this cluster with: kops edit cluster twfulfillment-uat.k8s.local * edit your node instance group: kops edit ig --name=twfulfillment-uat.k8s.local nodes * edit your master instance group: kops edit ig --name=twfulfillment-uat.k8s.local master-us-east-1a Finally configure your cluster with: kops update cluster twfulfillment-uat.k8s.local --yes Actual creation # ➜ k8s git:(feature/kubernetes) kops get cluster State Store: Required value: Please set the --state flag or export KOPS_STATE_STORE. A valid value follows the format s3://\u0026lt;bucket\u0026gt;. A s3 bucket is required to store cluster state information. ## Using explicit bucket ➜ k8s git:(feature/kubernetes) kops get cluster --state=s3://twfulfillment-k8s-uat NAME CLOUD ZONES twfulfillment-uat.k8s.local aws us-east-1a,us-east-1b ## GO! ➜ k8s git:(feature/kubernetes) kops update cluster twfulfillment-uat.k8s.local --state=s3://twfulfillment-k8s-uat --yes I0507 18:25:34.350553 59477 apply_cluster.go:456] Gossip DNS: skipping DNS validation I0507 18:25:35.281401 59477 executor.go:91] Tasks: 0 done / 79 total; 30 can run I0507 18:25:36.844750 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;ca\u0026#34; I0507 18:25:36.871653 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;apiserver-aggregator-ca\u0026#34; I0507 18:25:40.134585 59477 executor.go:91] Tasks: 30 done / 79 total; 25 can run I0507 18:25:41.669604 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;apiserver-aggregator\u0026#34; I0507 18:25:41.713562 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kubecfg\u0026#34; I0507 18:25:41.745488 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kubelet-api\u0026#34; I0507 18:25:41.785588 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kube-proxy\u0026#34; I0507 18:25:41.826068 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kops\u0026#34; I0507 18:25:41.828162 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kube-scheduler\u0026#34; I0507 18:25:41.834064 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kube-controller-manager\u0026#34; I0507 18:25:41.918415 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;apiserver-proxy-client\u0026#34; I0507 18:25:41.984042 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;kubelet\u0026#34; W0507 18:25:44.563905 59477 executor.go:118] error running task \u0026#34;SecurityGroup/api-elb.twfulfillment-uat.k8s.local\u0026#34; (9m55s remaining to succeed): error listing SecurityGroups: InvalidGroup.NotFound: The security group \u0026#39;sg-0747fcccc1c67f785\u0026#39; does not exist status code: 400, request id: 13a0c766-c04b-412b-bbbf-09ee76f11b72 I0507 18:25:44.563955 59477 executor.go:91] Tasks: 54 done / 79 total; 17 can run I0507 18:25:46.226024 59477 executor.go:91] Tasks: 71 done / 79 total; 6 can run I0507 18:25:48.356776 59477 executor.go:91] Tasks: 77 done / 79 total; 2 can run I0507 18:25:49.685752 59477 vfs_castore.go:731] Issuing new certificate: \u0026#34;master\u0026#34; W0507 18:25:50.745302 59477 executor.go:118] error running task \u0026#34;LoadBalancerAttachment/api-master-us-east-1a\u0026#34; (9m57s remaining to succeed): error attaching autoscaling group to ELB: ValidationError: Provided Load Balancers may not be valid. Please ensure they exist and try again. status code: 400, request id: 4d1ccf95-5213-11e8-92f5-11950813b91a I0507 18:25:50.745339 59477 executor.go:91] Tasks: 78 done / 79 total; 1 can run W0507 18:25:51.150152 59477 executor.go:118] error running task \u0026#34;LoadBalancerAttachment/api-master-us-east-1a\u0026#34; (9m57s remaining to succeed): error attaching autoscaling group to ELB: ValidationError: Provided Load Balancers may not be valid. Please ensure they exist and try again. status code: 400, request id: 4e822b8d-5213-11e8-aa30-b39cf8514ec9 I0507 18:25:51.150181 59477 executor.go:133] No progress made, sleeping before retrying 1 failed task(s) I0507 18:26:01.154620 59477 executor.go:91] Tasks: 78 done / 79 total; 1 can run I0507 18:26:02.115713 59477 executor.go:91] Tasks: 79 done / 79 total; 0 can run I0507 18:26:02.405109 59477 update_cluster.go:291] Exporting kubecfg for cluster kops has set your kubectl context to twfulfillment-uat.k8s.local Cluster is starting. It should be ready in a few minutes. Suggestions: * validate cluster: kops validate cluster * list nodes: kubectl get nodes --show-labels * ssh to the master: ssh -i ~/.ssh/id_rsa admin@api.twfulfillment-uat.k8s.local * the admin user is specific to Debian. If not using Debian please use the appropriate user based on your OS. * read about installing addons at: https://github.com/kubernetes/kops/blob/master/docs/addons.md. Validation # ➜ k8s git:(feature/kubernetes) kubectl cluster-info Kubernetes master is running at https://api-twfulfillment-uat-k8s-hqhbfl-2093835009.us-east-1.elb.amazonaws.com To further debug and diagnose cluster problems, use \u0026#39;kubectl cluster-info dump\u0026#39;. ➜ k8s git:(feature/kubernetes) ✗ kops validate cluster twfulfillment-uat.k8s.local --state=s3://twfulfillment-k8s-uat Validating cluster twfulfillment-uat.k8s.local INSTANCE GROUPS NAME ROLE MACHINETYPE MIN MAX SUBNETS master-us-east-1a Master t2.medium 1 1 us-east-1a nodes Node t2.medium 2 2 us-east-1a,us-east-1b NODE STATUS NAME ROLE READY ip-172-20-39-188.ec2.internal master True ip-172-20-54-148.ec2.internal node True ip-172-20-89-163.ec2.internal node True Your cluster twfulfillment-uat.k8s.local is ready ➜ k8s git:(feature/kubernetes) ✗ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-172-20-39-188.ec2.internal Ready master 2m v1.9.3 52.91.56.212 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-20-54-148.ec2.internal Ready node 2m v1.9.3 35.173.185.93 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-20-89-163.ec2.internal Ready node 2m v1.9.3 34.201.19.66 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ➜ k8s git:(feature/kubernetes) ✗ aws ec2 --region=us-east-1 describe-instances | jq \u0026#39;.Reservations[].Instances[] | .InstanceId + \u0026#34; : \u0026#34; + .KeyName + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress\u0026#39; \u0026#34;i-0b681568fcfd88a9b : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 52.91.56.212\u0026#34; \u0026#34;i-0f48b0acc1ebb3444 : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 35.173.185.93\u0026#34; \u0026#34;i-05fb02b4bdd61d9ae : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 52.91.149.121\u0026#34; \u0026#34;i-064d2261b5610715f : twfulfill-dev-us-east-1 =\u0026gt; \u0026#34; \u0026#34;i-034013fb3730e284b : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 54.162.224.243\u0026#34; \u0026#34;i-09268120fd4b2b95d : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 34.234.234.77\u0026#34; \u0026#34;i-007a536fedbdd74bc : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 34.201.19.66\u0026#34; ➜ k8s git:(feature/kubernetes) ✗ aws ec2 --region=us-east-1 describe-instances | jq \u0026#39;.Reservations[].Instances[] | .InstanceId + \u0026#34; : \u0026#34; + .Placement.AvailabilityZone + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress\u0026#39; \u0026#34;i-0b681568fcfd88a9b : us-east-1a =\u0026gt; 52.91.56.212\u0026#34; \u0026#34;i-0f48b0acc1ebb3444 : us-east-1a =\u0026gt; 35.173.185.93\u0026#34; \u0026#34;i-05fb02b4bdd61d9ae : us-east-1e =\u0026gt; 52.91.149.121\u0026#34; \u0026#34;i-064d2261b5610715f : us-east-1b =\u0026gt; \u0026#34; \u0026#34;i-034013fb3730e284b : us-east-1e =\u0026gt; 54.162.224.243\u0026#34; \u0026#34;i-09268120fd4b2b95d : us-east-1b =\u0026gt; 34.234.234.77\u0026#34; \u0026#34;i-007a536fedbdd74bc : us-east-1b =\u0026gt; 34.201.19.66\u0026#34; We repeat the process for DEV environment cluster\n➜ k8s git:(feature/kubernetes) ✗ kops create cluster --zones us-east-1c,us-east-1d --name twfulfillment-dev.k8s.local --ssh-public-key=./twfulfillment-dev-ssh.pub --state=s3://twfulfillment-k8s-dev --kubernetes-version 1.9.3 --node-count 2 --node-size t2.medium --master-size t2.medium I0507 18:43:22.701155 59817 create_cluster.go:1318] Using SSH public key: ./twfulfillment-dev-ssh.pub I0507 18:43:24.217861 59817 create_cluster.go:472] Inferred --cloud=aws from zone \u0026#34;us-east-1c\u0026#34; I0507 18:43:25.002584 59817 subnets.go:184] Assigned CIDR 172.20.32.0/19 to subnet us-east-1c I0507 18:43:25.002611 59817 subnets.go:184] Assigned CIDR 172.20.64.0/19 to subnet us-east-1d Previewing changes that will be made: ... DELETED ... ➜ k8s git:(feature/kubernetes) ✗ kops get cluster --state=s3://twfulfillment-k8s-dev NAME CLOUD ZONES twfulfillment-dev.k8s.local aws us-east-1c,us-east-1d ➜ k8s git:(feature/kubernetes) ✗ kops update cluster twfulfillment-dev.k8s.local --state=s3://twfulfillment-k8s-dev --yes I0507 18:45:09.825489 59851 apply_cluster.go:456] Gossip DNS: skipping DNS validation ... DELETED ... ➜ k8s git:(feature/kubernetes) ✗ kubectl config current-context twfulfillment-dev.k8s.local ➜ k8s git:(feature/kubernetes) ✗ kops validate cluster twfulfillment-dev.k8s.local --state=s3://twfulfillment-k8s-dev Validating cluster twfulfillment-dev.k8s.local INSTANCE GROUPS NAME ROLE MACHINETYPE MIN MAX SUBNETS master-us-east-1c Master t2.medium 1 1 us-east-1c nodes Node t2.medium 2 2 us-east-1c,us-east-1d NODE STATUS NAME ROLE READY ip-172-20-54-25.ec2.internal master True ip-172-20-61-51.ec2.internal node True ip-172-20-82-210.ec2.internal node True Your cluster twfulfillment-dev.k8s.local is ready ➜ k8s git:(feature/kubernetes) ✗ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-172-20-54-25.ec2.internal Ready master 1m v1.9.3 54.159.165.112 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-20-61-51.ec2.internal Ready node 52s v1.9.3 35.170.246.224 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ip-172-20-82-210.ec2.internal Ready node 50s v1.9.3 34.224.71.154 Debian GNU/Linux 8 (jessie) 4.4.115-k8s docker://17.3.2 ➜ k8s git:(feature/kubernetes) ✗ aws ec2 --region=us-east-1 describe-instances | jq \u0026#39;.Reservations[].Instances[] | .InstanceId + \u0026#34; : \u0026#34; + .Placement.AvailabilityZone + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress\u0026#39; \u0026#34;i-0b681568fcfd88a9b : us-east-1a =\u0026gt; 52.91.56.212\u0026#34; \u0026#34;i-039bc0f4b482127d6 : us-east-1d =\u0026gt; 34.224.71.154\u0026#34; \u0026#34;i-033d8a11120288ad6 : us-east-1c =\u0026gt; 35.170.246.224\u0026#34; \u0026#34;i-0f48b0acc1ebb3444 : us-east-1a =\u0026gt; 35.173.185.93\u0026#34; \u0026#34;i-05fb02b4bdd61d9ae : us-east-1e =\u0026gt; 52.91.149.121\u0026#34; \u0026#34;i-064d2261b5610715f : us-east-1b =\u0026gt; \u0026#34; \u0026#34;i-034013fb3730e284b : us-east-1e =\u0026gt; 54.162.224.243\u0026#34; \u0026#34;i-00fba10c6d2e2e9bb : us-east-1c =\u0026gt; 54.159.165.112\u0026#34; \u0026#34;i-09268120fd4b2b95d : us-east-1b =\u0026gt; 34.234.234.77\u0026#34; \u0026#34;i-007a536fedbdd74bc : us-east-1b =\u0026gt; 34.201.19.66\u0026#34; ➜ k8s git:(feature/kubernetes) ✗ aws ec2 --region=us-east-1 describe-instances | jq \u0026#39;.Reservations[].Instances[] | .InstanceId + \u0026#34; : \u0026#34; + .KeyName + \u0026#34; =\u0026gt; \u0026#34; + .PublicIpAddress\u0026#39; \u0026#34;i-0b681568fcfd88a9b : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 52.91.56.212\u0026#34; \u0026#34;i-039bc0f4b482127d6 : kubernetes.twfulfillment-dev.k8s.local-3c:05:ac:2d:75:14:21:fa:ab:98:c7:3d:9d:68:8d:1d =\u0026gt; 34.224.71.154\u0026#34; \u0026#34;i-033d8a11120288ad6 : kubernetes.twfulfillment-dev.k8s.local-3c:05:ac:2d:75:14:21:fa:ab:98:c7:3d:9d:68:8d:1d =\u0026gt; 35.170.246.224\u0026#34; \u0026#34;i-0f48b0acc1ebb3444 : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 35.173.185.93\u0026#34; \u0026#34;i-05fb02b4bdd61d9ae : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 52.91.149.121\u0026#34; \u0026#34;i-064d2261b5610715f : twfulfill-dev-us-east-1 =\u0026gt; \u0026#34; \u0026#34;i-034013fb3730e284b : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 54.162.224.243\u0026#34; \u0026#34;i-00fba10c6d2e2e9bb : kubernetes.twfulfillment-dev.k8s.local-3c:05:ac:2d:75:14:21:fa:ab:98:c7:3d:9d:68:8d:1d =\u0026gt; 54.159.165.112\u0026#34; \u0026#34;i-09268120fd4b2b95d : dockercloud-2a3769a0-fa94-458c-9e19-b4da1525ece8 =\u0026gt; 34.234.234.77\u0026#34; \u0026#34;i-007a536fedbdd74bc : kubernetes.twfulfillment-uat.k8s.local-c9:e4:2e:2e:a7:6d:f9:4b:d8:20:56:80:3b:2c:12:01 =\u0026gt; 34.201.19.66\u0026#34; Kubectl in local docker now will show multiple options\nlink to a post\n","date":"May 7, 2018","externalUrl":null,"permalink":"/posts/2018-05-07-k8s-from-scratch-kops/","section":"Posts","summary":"This describes creation of K8s cluster in AWS environment from scratch as done for microservices based eCommerce project.\nPre-requisites # AWS account access - IAM with Admin privileges AWS CLI installed - https://docs.aws.amazon.com/cli/latest/userguide/cli-install-macos.html CLI credentials (secret key + api Key) - https://docs.aws.amazon.com/cli/latest/reference/iam/index.html Kubectl and Kops local install ** see https://github.com/kubernetes/kops and https://kubernetes.io/docs/tasks/tools/install-kubectl/ Test of access # ➜ etc git:(feature/kubernetes) aws --version aws-cli/1.11.180 Python/3.6.4 Darwin/17.5.0 botocore/1.7.38 ➜ etc git:(feature/kubernetes) kubectl version Client Version: version.Info{Major:\"1\", Minor:\"10\", GitVersion:\"v1.10.1\", GitCommit:\"d4ab47518836c750f9949b9e0d387f20fb92260b\", GitTreeState:\"clean\", BuildDate:\"2018-04-13T22:27:55Z\", GoVersion:\"go1.9.5\", Compiler:\"gc\", Platform:\"darwin/amd64\"} Server Version: version.Info{Major:\"1\", Minor:\"9\", GitVersion:\"v1.9.3\", GitCommit:\"d2835416544f298c919e2ead3be3d0864b52323b\", GitTreeState:\"clean\", BuildDate:\"2018-02-07T11:55:20Z\", GoVersion:\"go1.9.2\", Compiler:\"gc\", Platform:\"linux/amd64\"} ➜ etc git:(feature/kubernetes) kops version Version 1.9.0 ➜ etc git:(feature/kubernetes) aws --profile twfulfill-miro iam list-users | jq '.Users[].UserName' .. DELETED ... \"twfulfillment.prod.miro.adamy\" .... Set the environment variables # These will be used by subsequent kops / aws commands\n","title":"Creating Kubernetes Cluster in AWS from scratch with kops","type":"post"},{"content":"","date":"May 7, 2018","externalUrl":null,"permalink":"/tags/kops/","section":"Tags","summary":"","title":"Kops","type":"tags"},{"content":"","date":"April 12, 2018","externalUrl":null,"permalink":"/tags/czechoslovakia/","section":"Tags","summary":"","title":"Czechoslovakia","type":"tags"},{"content":"He would be 74 today.\nPoet, singer, master of Czech language and symbol of resistance during dark years 1968-1989.\n","date":"April 12, 2018","externalUrl":null,"permalink":"/posts/2018-04-12-karel/","section":"Posts","summary":"He would be 74 today.\nPoet, singer, master of Czech language and symbol of resistance during dark years 1968-1989.\n","title":"Remembering Karel Kryl","type":"post"},{"content":"","date":"March 6, 2018","externalUrl":null,"permalink":"/tags/czech/","section":"Tags","summary":"","title":"Czech","type":"tags"},{"content":"","date":"March 6, 2018","externalUrl":null,"permalink":"/tags/english/","section":"Tags","summary":"","title":"English","type":"tags"},{"content":"This is how my mind often works, triggered by using 4 languages every day and 5-6 every week\n","date":"March 6, 2018","externalUrl":null,"permalink":"/posts/2018-03-05-poly/","section":"Posts","summary":"This is how my mind often works, triggered by using 4 languages every day and 5-6 every week\n","title":"Europanto","type":"post"},{"content":"","date":"March 6, 2018","externalUrl":null,"permalink":"/tags/german/","section":"Tags","summary":"","title":"German","type":"tags"},{"content":"","date":"March 6, 2018","externalUrl":null,"permalink":"/tags/slovak/","section":"Tags","summary":"","title":"Slovak","type":"tags"},{"content":"Hiking trip - El Barranc de L\u0026rsquo;Infern. (Ruta de los 6000 escalones) - https://es.wikiloc.com/rutas-senderismo/vall-de-laguar-la-catedral-del-senderismo-pr-v-147-el-barranc-de-linfern-ruta-de-los-6000-escalones-11632646\nSeeing almods in bloom was added benefit.\n","date":"February 26, 2018","externalUrl":null,"permalink":"/posts/2018-02-26-almonds/","section":"Posts","summary":"Hiking trip - El Barranc de L’Infern. (Ruta de los 6000 escalones) - https://es.wikiloc.com/rutas-senderismo/vall-de-laguar-la-catedral-del-senderismo-pr-v-147-el-barranc-de-linfern-ruta-de-los-6000-escalones-11632646\nSeeing almods in bloom was added benefit.\n","title":"Spring is in the air","type":"post"},{"content":"","date":"February 10, 2018","externalUrl":null,"permalink":"/tags/atg/","section":"Tags","summary":"","title":"Atg","type":"tags"},{"content":"I have found local clone of this repo while cleaning up the disk. The source was originally residing in private repo on Bitbucket which I moved to GitHub: https://github.com/miroadamy/atgdiagram\nWhat it does # Groovy scripts:\nhttps://github.com/miroadamy/atgdiagram/blob/master/src/listATGModules.groovy https://github.com/miroadamy/atgdiagram/blob/master/src/ATGModule.groovy that scan local ATG installation, discover modules and generate the PlantUML file representing it, for example - https://github.com/miroadamy/atgdiagram/blob/master/uml/test2.uml\nUsing ATG_ROOT from environment variable $ATG_ROOT: /opt/ATG/ATG10.0.2 Using /opt/ATG/ATG10.0.2 installation Dependants of module TWeStore.eStore =\u0026gt; [DCS.Search.Query, B2CCommerce, DAF.Search.Query, DAF.Search.Base, DCS.Search.common, DPS.Search.Index, DAF.Search.common, DAS-UI, DCS.Search.Index, DPS, DCS, DCS.Search.CustomCatalogs, DCS.Search.CustomCatalogs.Query, DCS.Search.CustomCatalogs.Index, DAF.Search.Routing, DCS.Search.CustomCatalogs.common, DAF.Search.Index, DSS, DCS.CustomCatalogs, DAS] @startuml Object TWeStore_eStore Object DCS Object B2CCommerce Object DCS_Search_CustomCatalogs Object DAF_Search_Routing Object DCS_CustomCatalogs Object DPS Object DCS_Search_CustomCatalogs_Query Object DAF_Search_Base Object DCS_Search_CustomCatalogs_Index Object DSS Object DAS_UI Object DCS_Search_Query Object DCS_Search_CustomCatalogs_common Object DAS Object DCS_Search_Index Object DAF_Search_Query Object DCS_Search_common Object DPS_Search_Index Object DAF_Search_Index Object DAF_Search_common TWeStore_eStore \u0026lt;|-- DCS TWeStore_eStore \u0026lt;|-- DCS_CustomCatalogs TWeStore_eStore \u0026lt;|-- B2CCommerce TWeStore_eStore \u0026lt;|-- DCS_Search_CustomCatalogs TWeStore_eStore \u0026lt;|-- DAF_Search_Routing DCS \u0026lt;|-- DPS DCS \u0026lt;|-- DSS B2CCommerce \u0026lt;|-- DCS DCS_Search_CustomCatalogs \u0026lt;|-- DCS_Search_CustomCatalogs_Index DCS_Search_CustomCatalogs \u0026lt;|-- DCS_Search_CustomCatalogs_Query DAF_Search_Routing \u0026lt;|-- DAS_UI DAF_Search_Routing \u0026lt;|-- DAF_Search_Base DCS_CustomCatalogs \u0026lt;|-- DCS DPS \u0026lt;|-- DAS DCS_Search_CustomCatalogs_Query \u0026lt;|-- DCS_Search_Query DCS_Search_CustomCatalogs_Query \u0026lt;|-- DCS_Search_CustomCatalogs_common DAF_Search_Base \u0026lt;|-- DAS_UI DCS_Search_CustomCatalogs_Index \u0026lt;|-- DCS_Search_Index DCS_Search_CustomCatalogs_Index \u0026lt;|-- DCS_Search_CustomCatalogs_common DSS \u0026lt;|-- DPS DAS_UI \u0026lt;|-- DAS DCS_Search_Query \u0026lt;|-- DAF_Search_Query DCS_Search_Query \u0026lt;|-- DCS_Search_common DCS_Search_Query \u0026lt;|-- DCS DCS_Search_CustomCatalogs_common \u0026lt;|-- DCS_Search_common DCS_Search_CustomCatalogs_common \u0026lt;|-- DCS_CustomCatalogs DCS_Search_Index \u0026lt;|-- DPS_Search_Index DCS_Search_Index \u0026lt;|-- DCS_Search_common DCS_Search_Index \u0026lt;|-- DCS DAF_Search_Query \u0026lt;|-- DAF_Search_common DCS_Search_common \u0026lt;|-- DAF_Search_common DCS_Search_common \u0026lt;|-- DCS DPS_Search_Index \u0026lt;|-- DPS DPS_Search_Index \u0026lt;|-- DAF_Search_Index DAF_Search_Index \u0026lt;|-- DAS_UI DAF_Search_Index \u0026lt;|-- DAF_Search_Base DAF_Search_common \u0026lt;|-- DAS_UI DAF_Search_common \u0026lt;|-- DAF_Search_Base DAF_Search_common \u0026lt;|-- DAF_Search_Routing @enduml This UML file is the processed by PlantUML\n#!/bin/sh PLANTUML_HOME=/opt/diagrams if [ ! -e $PLANTUML_HOME ] then echo There is no PLANT UML installation at \\$PLANTUML_HOME=$PLANTUML_HOME exit 1 fi if [ \u0026#34;x\u0026#34; == \u0026#34;x$1\u0026#34; ] then echo Usage: $0 UML-FILE-TO-PROCESS exit 2 fi java -Xmx1024m -jar $PLANTUML_HOME/plantuml.jar $1 and renders this\n","date":"February 10, 2018","externalUrl":null,"permalink":"/posts/2018-02-10-atgdiagram/","section":"Posts","summary":"I have found local clone of this repo while cleaning up the disk. The source was originally residing in private repo on Bitbucket which I moved to GitHub: https://github.com/miroadamy/atgdiagram\nWhat it does # Groovy scripts:\nhttps://github.com/miroadamy/atgdiagram/blob/master/src/listATGModules.groovy https://github.com/miroadamy/atgdiagram/blob/master/src/ATGModule.groovy that scan local ATG installation, discover modules and generate the PlantUML file representing it, for example - https://github.com/miroadamy/atgdiagram/blob/master/uml/test2.uml\nUsing ATG_ROOT from environment variable $ATG_ROOT: /opt/ATG/ATG10.0.2 Using /opt/ATG/ATG10.0.2 installation Dependants of module TWeStore.eStore =\u003e [DCS.Search.Query, B2CCommerce, DAF.Search.Query, DAF.Search.Base, DCS.Search.common, DPS.Search.Index, DAF.Search.common, DAS-UI, DCS.Search.Index, DPS, DCS, DCS.Search.CustomCatalogs, DCS.Search.CustomCatalogs.Query, DCS.Search.CustomCatalogs.Index, DAF.Search.Routing, DCS.Search.CustomCatalogs.common, DAF.Search.Index, DSS, DCS.CustomCatalogs, DAS] @startuml Object TWeStore_eStore Object DCS Object B2CCommerce Object DCS_Search_CustomCatalogs Object DAF_Search_Routing Object DCS_CustomCatalogs Object DPS Object DCS_Search_CustomCatalogs_Query Object DAF_Search_Base Object DCS_Search_CustomCatalogs_Index Object DSS Object DAS_UI Object DCS_Search_Query Object DCS_Search_CustomCatalogs_common Object DAS Object DCS_Search_Index Object DAF_Search_Query Object DCS_Search_common Object DPS_Search_Index Object DAF_Search_Index Object DAF_Search_common TWeStore_eStore \u003c|-- DCS TWeStore_eStore \u003c|-- DCS_CustomCatalogs TWeStore_eStore \u003c|-- B2CCommerce TWeStore_eStore \u003c|-- DCS_Search_CustomCatalogs TWeStore_eStore \u003c|-- DAF_Search_Routing DCS \u003c|-- DPS DCS \u003c|-- DSS B2CCommerce \u003c|-- DCS DCS_Search_CustomCatalogs \u003c|-- DCS_Search_CustomCatalogs_Index DCS_Search_CustomCatalogs \u003c|-- DCS_Search_CustomCatalogs_Query DAF_Search_Routing \u003c|-- DAS_UI DAF_Search_Routing \u003c|-- DAF_Search_Base DCS_CustomCatalogs \u003c|-- DCS DPS \u003c|-- DAS DCS_Search_CustomCatalogs_Query \u003c|-- DCS_Search_Query DCS_Search_CustomCatalogs_Query \u003c|-- DCS_Search_CustomCatalogs_common DAF_Search_Base \u003c|-- DAS_UI DCS_Search_CustomCatalogs_Index \u003c|-- DCS_Search_Index DCS_Search_CustomCatalogs_Index \u003c|-- DCS_Search_CustomCatalogs_common DSS \u003c|-- DPS DAS_UI \u003c|-- DAS DCS_Search_Query \u003c|-- DAF_Search_Query DCS_Search_Query \u003c|-- DCS_Search_common DCS_Search_Query \u003c|-- DCS DCS_Search_CustomCatalogs_common \u003c|-- DCS_Search_common DCS_Search_CustomCatalogs_common \u003c|-- DCS_CustomCatalogs DCS_Search_Index \u003c|-- DPS_Search_Index DCS_Search_Index \u003c|-- DCS_Search_common DCS_Search_Index \u003c|-- DCS DAF_Search_Query \u003c|-- DAF_Search_common DCS_Search_common \u003c|-- DAF_Search_common DCS_Search_common \u003c|-- DCS DPS_Search_Index \u003c|-- DPS DPS_Search_Index \u003c|-- DAF_Search_Index DAF_Search_Index \u003c|-- DAS_UI DAF_Search_Index \u003c|-- DAF_Search_Base DAF_Search_common \u003c|-- DAS_UI DAF_Search_common \u003c|-- DAF_Search_Base DAF_Search_common \u003c|-- DAF_Search_Routing @enduml This UML file is the processed by PlantUML\n","title":"ATG Module Diagram Generator","type":"post"},{"content":"","date":"February 10, 2018","externalUrl":null,"permalink":"/tags/groovy/","section":"Tags","summary":"","title":"Groovy","type":"tags"},{"content":"","date":"February 10, 2018","externalUrl":null,"permalink":"/tags/plantuml/","section":"Tags","summary":"","title":"Plantuml","type":"tags"},{"content":"We have visited Canada for the winter season.\nIt was very nice to see old friends and family.\n","date":"January 26, 2018","externalUrl":null,"permalink":"/posts/2017-01-26-canada/","section":"Posts","summary":"We have visited Canada for the winter season.\nIt was very nice to see old friends and family.\n","title":"Christmas in Canada","type":"post"},{"content":"","date":"November 23, 2017","externalUrl":null,"permalink":"/tags/monitoring/","section":"Tags","summary":"","title":"Monitoring","type":"tags"},{"content":"","date":"November 23, 2017","externalUrl":null,"permalink":"/tags/virtualization/","section":"Tags","summary":"","title":"Virtualization","type":"tags"},{"content":" The idea / motivation # In order to run VisualVM from predefined configuration you need to point the app to the user directory. This directory takes about 20MB, but 90% of the the content is actually generated or repeated.\n➜ 4devops-visualvm git:(master) du -sh tw-sl/* 244K tw-sl/config 7.3M tw-sl/modules 52K tw-sl/repository 4.0K tw-sl/update 104K tw-sl/update_tracking 11M tw-sl/var ➜ 4devops-visualvm git:(master) du -sh tw-wool/* 248K tw-wool/config 7.2M tw-wool/modules 60K tw-wool/repository 4.0K tw-wool/update 104K tw-wool/update_tracking 11M tw-wool/var ➜ 4devops-visualvm git:(master) du -sh tw-wool 19M tw-wool The only part that is specific and worthy of maintaining in the Git repo is repository\n➜ 4devops-visualvm git:(master) du -sh tw-wool/repository/* 16K tw-wool/repository/hosts 44K tw-wool/repository/jmxapplications ➜ 4devops-visualvm git:(master) tree tw-wool/repository tw-wool/repository ├── hosts │ ├── 10.206.8.130.properties │ ├── 10.206.8.131.properties │ ├── 10.206.8.134.properties │ └── 10.206.8.35.properties └── jmxapplications ├── 1445526765721.jmx │ └── jmxapplication.properties ├── 1445526765722.jmx │ └── jmxapplication.properties ├── 1445526765723.jmx │ └── jmxapplication.properties ├── 1445526765724.jmx │ └── jmxapplication.properties ├── 1445526765725.jmx │ └── jmxapplication.properties ├── 1445526765726.jmx │ └── jmxapplication.properties ├── 1445526765727.jmx │ └── jmxapplication.properties ├── 1445526765728.jmx │ └── jmxapplication.properties ├── 1445526765729.jmx │ └── jmxapplication.properties ├── 1445526765730.jmx │ └── jmxapplication.properties └── 1445526765731.jmx └── jmxapplication.properties 13 directories, 15 files which contains the hosts and JMX app definitions\nIdeally, we would want to have Docker container that would encapsulate the VisualVM install and provide as external volume only the configuration part. This part is small enough (and textual) so that it can be maintained efficiently in Git while the common and generated files(rest of the 20MB) will be inside container\nQuick and dirty solution # For this to work, we need Docker container capable of running GUI application and efficient client access (e.g. VNC)\nStarting point is https://github.com/ConSol/docker-headless-vnc-container\nI have tested the container and selected xfce+ubuntu for start\n➜ ~ docker run -d -p 5901:5901 -p 6901:6901 -e VNC_RESOLUTION=800x600 consol/ubuntu-icewm-vnc ➜ ~ docker run -d -p 5901:5901 -p 6901:6901 consol/centos-xfce-vnc Connect with JollyFastVNCPro - port 5901 / vncpassword or http://localhost:6901/ I have installed inside this container visualVM, ssh client using docker exec and made commit (actually, 3 commits).\nThe result is available at thinkwrap/ubuntu-xfce-vnc-visualvm:v3 (private image)\nHow to use it # Create local directory for the shared information containing only hosts and JMX property files. Here is mine\n➜ test-config tree sim-prod sim-prod └── repository ├── hosts │ ├── 10.200.137.34.properties │ ├── 10.200.137.50.properties │ ├── 10.200.137.51.properties │ ├── 10.200.137.52.properties │ └── 10.200.137.53.properties └── jmxapplications 3 directories, 5 files ➜ test-config ll total 32 -rw-r--r--@ 1 miro staff 16K 19 Nov 20:43 hosts-file drwxr-xr-x 3 miro staff 96B 19 Nov 20:35 sim-prod Also, copy the /etc/hosts file as hosts-file so that Docker uses your known mappings\nStart container with desired resolution and 2 volumes - one for mapped config and one for hostfile\ntest-config docker run -d -p 5901:5901 -p 6901:6901 -e VNC_RESOLUTION=800x600 -v /Users/miro/src/DEVOPS/test-config/sim-prod/repository:/headless/.visualvm/1.3.8/repository -v /Users/miro/src/DEVOPS/test-config/hosts-file:/etc/hosts thinkwrap/ubuntu-xfce-vnc-visualvm:v3 e12adcb030a5706f246253ccc93823920a0494b5ae962eb54b8ce2b9627bdbc4 Connect via Web or via VNC client (use vncpassword as vnc password). Degree of uglyness will depend on the client used. The URL to connect to is localhost:5901.\nOn Mac, you can use OOTB Share Screen app with URL vnc://localhost:5901\nStart VisualVM using shortcut - note that provided config is loaded\n","date":"November 23, 2017","externalUrl":null,"permalink":"/posts/2017-11-23-visual-vm/","section":"Posts","summary":"The idea / motivation # In order to run VisualVM from predefined configuration you need to point the app to the user directory. This directory takes about 20MB, but 90% of the the content is actually generated or repeated.\n➜ 4devops-visualvm git:(master) du -sh tw-sl/* 244K tw-sl/config 7.3M tw-sl/modules 52K tw-sl/repository 4.0K tw-sl/update 104K tw-sl/update_tracking 11M tw-sl/var ➜ 4devops-visualvm git:(master) du -sh tw-wool/* 248K tw-wool/config 7.2M tw-wool/modules 60K tw-wool/repository 4.0K tw-wool/update 104K tw-wool/update_tracking 11M tw-wool/var ➜ 4devops-visualvm git:(master) du -sh tw-wool 19M tw-wool The only part that is specific and worthy of maintaining in the Git repo is repository\n","title":"VisualVM inside Docker container","type":"post"},{"content":" Install AWS CLI on Mac # The Mac comes with Python 2.7 and no pip\nThis guide recommends upgrade to Python 3 which I want to avoid: http://docs.aws.amazon.com/cli/latest/userguide/cli-install-macos.html\nUnsuccesfull path - keep the Python 2.7 # ➜ ~ pip --version zsh: command not found: pip ➜ ~ sudo easy_install pip Password: Searching for pip Reading https://pypi.python.org/simple/pip/ Best match: pip 9.0.1 Downloading https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9 Processing pip-9.0.1.tar.gz Writing /tmp/easy_install-QnLLJp/pip-9.0.1/setup.cfg Running pip-9.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-QnLLJp/pip-9.0.1/egg-dist-tmp-03hMh7 /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: \u0026#39;python_requires\u0026#39; warnings.warn(msg) warning: no previously-included files found matching \u0026#39;.coveragerc\u0026#39; warning: no previously-included files found matching \u0026#39;.mailmap\u0026#39; warning: no previously-included files found matching \u0026#39;.travis.yml\u0026#39; warning: no previously-included files found matching \u0026#39;.landscape.yml\u0026#39; warning: no previously-included files found matching \u0026#39;pip/_vendor/Makefile\u0026#39; warning: no previously-included files found matching \u0026#39;tox.ini\u0026#39; warning: no previously-included files found matching \u0026#39;dev-requirements.txt\u0026#39; warning: no previously-included files found matching \u0026#39;appveyor.yml\u0026#39; no previously-included directories found matching \u0026#39;.github\u0026#39; no previously-included directories found matching \u0026#39;.travis\u0026#39; no previously-included directories found matching \u0026#39;docs/_build\u0026#39; no previously-included directories found matching \u0026#39;contrib\u0026#39; no previously-included directories found matching \u0026#39;tasks\u0026#39; no previously-included directories found matching \u0026#39;tests\u0026#39; creating /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg Extracting pip-9.0.1-py2.7.egg to /Library/Python/2.7/site-packages Adding pip 9.0.1 to easy-install.pth file Installing pip script to /usr/local/bin Installing pip2.7 script to /usr/local/bin Installing pip2 script to /usr/local/bin Installed /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg Processing dependencies for pip Finished processing dependencies for pip ➜ ~ pip --version pip 9.0.1 from /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7) ➜ ~ pip install awscli --upgrade --user Collecting awscli Downloading awscli-1.11.185-py2.py3-none-any.whl (1.2MB) 100% |████████████████████████████████| 1.2MB 1.1MB/s Collecting colorama\u0026lt;=0.3.7,\u0026gt;=0.2.5 (from awscli) Downloading colorama-0.3.7-py2.py3-none-any.whl Collecting s3transfer\u0026lt;0.2.0,\u0026gt;=0.1.9 (from awscli) Downloading s3transfer-0.1.11-py2.py3-none-any.whl (54kB) 100% |████████████████████████████████| 61kB 6.2MB/s Collecting botocore==1.7.43 (from awscli) Downloading botocore-1.7.43-py2.py3-none-any.whl (3.7MB) 100% |████████████████████████████████| 3.7MB 363kB/s Collecting docutils\u0026gt;=0.10 (from awscli) Downloading docutils-0.14-py2-none-any.whl (543kB) 100% |████████████████████████████████| 552kB 2.4MB/s Collecting rsa\u0026lt;=3.5.0,\u0026gt;=3.1.2 (from awscli) Downloading rsa-3.4.2-py2.py3-none-any.whl (46kB) 100% |████████████████████████████████| 51kB 5.9MB/s Collecting PyYAML\u0026lt;=3.12,\u0026gt;=3.10 (from awscli) Downloading PyYAML-3.12.tar.gz (253kB) 100% |████████████████████████████████| 256kB 3.5MB/s Collecting futures\u0026lt;4.0.0,\u0026gt;=2.2.0; python_version == \u0026#34;2.6\u0026#34; or python_version == \u0026#34;2.7\u0026#34; (from s3transfer\u0026lt;0.2.0,\u0026gt;=0.1.9-\u0026gt;awscli) Downloading futures-3.1.1-py2-none-any.whl Collecting jmespath\u0026lt;1.0.0,\u0026gt;=0.7.1 (from botocore==1.7.43-\u0026gt;awscli) Downloading jmespath-0.9.3-py2.py3-none-any.whl Collecting python-dateutil\u0026lt;3.0.0,\u0026gt;=2.1 (from botocore==1.7.43-\u0026gt;awscli) Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB) 100% |████████████████████████████████| 194kB 4.5MB/s Collecting pyasn1\u0026gt;=0.1.3 (from rsa\u0026lt;=3.5.0,\u0026gt;=3.1.2-\u0026gt;awscli) Downloading pyasn1-0.3.7-py2.py3-none-any.whl (63kB) 100% |████████████████████████████████| 71kB 7.8MB/s Collecting six\u0026gt;=1.5 (from python-dateutil\u0026lt;3.0.0,\u0026gt;=2.1-\u0026gt;botocore==1.7.43-\u0026gt;awscli) Downloading six-1.11.0-py2.py3-none-any.whl Installing collected packages: colorama, futures, jmespath, docutils, six, python-dateutil, botocore, s3transfer, pyasn1, rsa, PyYAML, awscli Running setup.py install for PyYAML ... done Successfully installed PyYAML-3.12 awscli-1.11.185 botocore-1.7.43 colorama-0.3.7 docutils-0.14 futures-3.1.1 jmespath-0.9.3 pyasn1-0.3.7 python-dateutil-2.6.1 rsa-3.4.2 s3transfer-0.1.11 six-1.11.0 ➜ ~ aws --version zsh: command not found: aws ➜ ~ sw_vers ProductName: Mac OS X ProductVersion: 10.13.1 BuildVersion: 17B48 This does not work.\nThere is no aws script in ~/.local/bin, the pip install just added som python libraries\n=\u0026gt; Repeating did not help either\nRequirement already up-to-date: awscli in ./Library/Python/2.7/lib/python/site-packages Requirement already up-to-date: colorama\u0026lt;=0.3.7,\u0026gt;=0.2.5 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: s3transfer\u0026lt;0.2.0,\u0026gt;=0.1.9 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: botocore==1.7.43 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: docutils\u0026gt;=0.10 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: rsa\u0026lt;=3.5.0,\u0026gt;=3.1.2 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: PyYAML\u0026lt;=3.12,\u0026gt;=3.10 in ./Library/Python/2.7/lib/python/site-packages (from awscli) Requirement already up-to-date: futures\u0026lt;4.0.0,\u0026gt;=2.2.0; python_version == \u0026#34;2.6\u0026#34; or python_version == \u0026#34;2.7\u0026#34; in ./Library/Python/2.7/lib/python/site-packages (from s3transfer\u0026lt;0.2.0,\u0026gt;=0.1.9-\u0026gt;awscli) Requirement already up-to-date: jmespath\u0026lt;1.0.0,\u0026gt;=0.7.1 in ./Library/Python/2.7/lib/python/site-packages (from botocore==1.7.43-\u0026gt;awscli) Requirement already up-to-date: python-dateutil\u0026lt;3.0.0,\u0026gt;=2.1 in ./Library/Python/2.7/lib/python/site-packages (from botocore==1.7.43-\u0026gt;awscli) Requirement already up-to-date: pyasn1\u0026gt;=0.1.3 in ./Library/Python/2.7/lib/python/site-packages (from rsa\u0026lt;=3.5.0,\u0026gt;=3.1.2-\u0026gt;awscli) Requirement already up-to-date: six\u0026gt;=1.5 in ./Library/Python/2.7/lib/python/site-packages (from python-dateutil\u0026lt;3.0.0,\u0026gt;=2.1-\u0026gt;botocore==1.7.43-\u0026gt;awscli) Simple and working - brew to the rescue # Redoing with brew =\u0026gt; installs Python 3 :-( but it works\n➜ ~ brew install awscli Updating Homebrew... ==\u0026gt; Auto-updated Homebrew! Updated 1 tap (homebrew/core). ==\u0026gt; New Formulae dps8m heartbeat simg2img e2tools kaitai-struct-compiler ==\u0026gt; Updated Formulae libuv ✔ exploitdb grpc logstash paket singular abcmidi faac gsmartcontrol mdds pandoc sjk amazon-ecs-cli faas-cli harfbuzz mercurial pandoc-crossref solr apibuilder-cli ffmpeg@2.8 i2p mighttpd2 pcl source-to-image asciidoc firebase-cli imagemagick mikutter pipenv sourcekitten b2-tools flow imagemagick@6 mingw-w64 poco supersonic babl fluent-bit influxdb mosh poppler swift-protobuf bash-snippets fn inspircd mupdf postgresql swiftformat bazel folly iron-functions mupdf-tools postgresql@9.4 swiftlint bchunk frugal itstool mypy postgresql@9.5 temporal_tables binaryen gdcm jenkins nativefier postgresql@9.6 terragrunt bit gegl jenkins-lts nco pre-commit tintin bitrise getdns jfrog-cli-go ncview prometheus upscaledb buku geth jruby netcdf protobuf urh cmake git-annex kerl nickle protobuf-c vapoursynth convox git-cinnabar kubectx node-build protobuf-swift vtk couchdb gjstest libgsf ntl pumba wireguard-tools cppad glide libmaxminddb nuttcp resty xtensor dbus gmt libogg omniorb ringojs yara debianutils gmt@4 libopusenc ompl sassc zabbix docfx gofabric8 libphonenumber opencoarrays scalaenv zbackup dssim grafana libpq ortp scalastyle zenity erlang grakn libpqxx packetq scm-manager zimg ==\u0026gt; Renamed Formulae newsbeuter -\u0026gt; newsboat ==\u0026gt; Installing dependencies for awscli: pkg-config, sqlite, openssl, python3 ==\u0026gt; Installing awscli dependency: pkg-config ==\u0026gt; Downloading https://homebrew.bintray.com/bottles/pkg-config-0.29.2.high_sierra.bottle.tar.gz ==\u0026gt; Downloading from https://akamai.bintray.com/f1/f1b29fb5388dccab0fcaf665ab43d308ee51816b24262417bf83a686b6e30 ######################################################################## 100.0% ==\u0026gt; Pouring pkg-config-0.29.2.high_sierra.bottle.tar.gz 🍺 /usr/local/Cellar/pkg-config/0.29.2: 11 files, 627.2KB ==\u0026gt; Installing awscli dependency: sqlite ==\u0026gt; Downloading https://homebrew.bintray.com/bottles/sqlite-3.21.0.high_sierra.bottle.tar.gz ==\u0026gt; Downloading from https://akamai.bintray.com/7d/7d2f6274d626acafed914d37e953cac4e33022eb889c6998af19bf1932270 ######################################################################## 100.0% ==\u0026gt; Pouring sqlite-3.21.0.high_sierra.bottle.tar.gz ==\u0026gt; Caveats This formula is keg-only, which means it was not symlinked into /usr/local, because macOS provides an older sqlite3. If you need to have this software first in your PATH run: echo \u0026#39;export PATH=\u0026#34;/usr/local/opt/sqlite/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.zshrc For compilers to find this software you may need to set: LDFLAGS: -L/usr/local/opt/sqlite/lib CPPFLAGS: -I/usr/local/opt/sqlite/include For pkg-config to find this software you may need to set: PKG_CONFIG_PATH: /usr/local/opt/sqlite/lib/pkgconfig ==\u0026gt; Summary 🍺 /usr/local/Cellar/sqlite/3.21.0: 11 files, 3.0MB ==\u0026gt; Installing awscli dependency: openssl ==\u0026gt; Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2m.high_sierra.bottle.tar.gz ==\u0026gt; Downloading from https://akamai.bintray.com/0e/0eeee936b7f362ec5d2d844deb74ec92b79d3105445e5ca5e8767df4aabde ######################################################################## 100.0% ==\u0026gt; Pouring openssl-1.0.2m.high_sierra.bottle.tar.gz ==\u0026gt; Caveats A CA file has been bootstrapped using certificates from the SystemRoots keychain. To add additional certificates (e.g. the certificates added in the System keychain), place .pem files in /usr/local/etc/openssl/certs and run /usr/local/opt/openssl/bin/c_rehash This formula is keg-only, which means it was not symlinked into /usr/local, because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries. If you need to have this software first in your PATH run: echo \u0026#39;export PATH=\u0026#34;/usr/local/opt/openssl/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; ~/.zshrc For compilers to find this software you may need to set: LDFLAGS: -L/usr/local/opt/openssl/lib CPPFLAGS: -I/usr/local/opt/openssl/include For pkg-config to find this software you may need to set: PKG_CONFIG_PATH: /usr/local/opt/openssl/lib/pkgconfig ==\u0026gt; Summary 🍺 /usr/local/Cellar/openssl/1.0.2m: 1,792 files, 12.3MB ==\u0026gt; Installing awscli dependency: python3 Warning: Building python3 from source: The bottle needs the Apple Command Line Tools to be installed. You can install them, if desired, with: xcode-select --install ==\u0026gt; Downloading https://www.python.org/ftp/python/3.6.3/Python-3.6.3.tar.xz ######################################################################## 100.0% ==\u0026gt; ./configure --prefix=/usr/local/Cellar/python3/3.6.3 --enable-ipv6 --datarootdir=/usr/local/Cellar/python3/3 ==\u0026gt; make ==\u0026gt; make install PYTHONAPPSDIR=/usr/local/Cellar/python3/3.6.3 ==\u0026gt; make frameworkinstallextras PYTHONAPPSDIR=/usr/local/Cellar/python3/3.6.3/share/python3 ==\u0026gt; Downloading https://files.pythonhosted.org/packages/a4/c8/9a7a47f683d54d83f648d37c3e180317f80dc126a304c45dc6 ######################################################################## 100.0% ==\u0026gt; Downloading https://files.pythonhosted.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c6 ######################################################################## 100.0% ==\u0026gt; Downloading https://files.pythonhosted.org/packages/fa/b4/f9886517624a4dcb81a1d766f68034344b7565db69f13d5269 ######################################################################## 100.0% ==\u0026gt; /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-sc ==\u0026gt; /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-sc ==\u0026gt; /usr/local/Cellar/python3/3.6.3/bin/python3 -s setup.py --no-user-cfg install --force --verbose --install-sc ==\u0026gt; Caveats Pip, setuptools, and wheel have been installed. To update them pip3 install --upgrade pip setuptools wheel You can install Python packages with pip3 install \u0026lt;package\u0026gt; They will install into the site-package directory /usr/local/lib/python3.6/site-packages See: https://docs.brew.sh/Homebrew-and-Python.html ==\u0026gt; Summary 🍺 /usr/local/Cellar/python3/3.6.3: 7,973 files, 111MB, built in 2 minutes 14 seconds ==\u0026gt; Installing awscli ==\u0026gt; Downloading https://homebrew.bintray.com/bottles/awscli-1.11.180_1.high_sierra.bottle.tar.gz ==\u0026gt; Downloading from https://akamai.bintray.com/16/168d726049366b4cbd1278e0e4a4e0e7e406d555e13e3681a968ca629776c ######################################################################## 100.0% ==\u0026gt; Pouring awscli-1.11.180_1.high_sierra.bottle.tar.gz ==\u0026gt; Caveats The \u0026#34;examples\u0026#34; directory has been installed to: /usr/local/share/awscli/examples Bash completion has been installed to: /usr/local/etc/bash_completion.d zsh completions and functions have been installed to: /usr/local/share/zsh/site-functions ==\u0026gt; Summary 🍺 /usr/local/Cellar/awscli/1.11.180_1: 4,119 files, 35.8MB ➜ ~ aws --version aws-cli/1.11.180 Python/3.6.3 Darwin/17.2.0 botocore/1.7.38 ➜ ~ python --version Python 2.7.10 ➜ ~ python3 --version Python 3.6.3 ➜ ~ pip --version pip 9.0.1 from /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7) ➜ ~ pip3 --version pip 9.0.1 from /usr/local/lib/python3.6/site-packages (python 3.6) Main reason why I was trying to avoid Python3 were some Python2 tools that were reportedly broken by presence of Python3.\nLuckily, it turns out I have both python and python3 working afterward\n","date":"November 14, 2017","externalUrl":null,"permalink":"/posts/2017-11-14-install-aws-cli-mac/","section":"Posts","summary":"Install AWS CLI on Mac # The Mac comes with Python 2.7 and no pip\nThis guide recommends upgrade to Python 3 which I want to avoid: http://docs.aws.amazon.com/cli/latest/userguide/cli-install-macos.html\nUnsuccesfull path - keep the Python 2.7 # ➜ ~ pip --version zsh: command not found: pip ➜ ~ sudo easy_install pip Password: Searching for pip Reading https://pypi.python.org/simple/pip/ Best match: pip 9.0.1 Downloading https://pypi.python.org/packages/11/b6/abcb525026a4be042b486df43905d6893fb04f05aac21c32c638e939e447/pip-9.0.1.tar.gz#md5=35f01da33009719497f01a4ba69d63c9 Processing pip-9.0.1.tar.gz Writing /tmp/easy_install-QnLLJp/pip-9.0.1/setup.cfg Running pip-9.0.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-QnLLJp/pip-9.0.1/egg-dist-tmp-03hMh7 /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: 'python_requires' warnings.warn(msg) warning: no previously-included files found matching '.coveragerc' warning: no previously-included files found matching '.mailmap' warning: no previously-included files found matching '.travis.yml' warning: no previously-included files found matching '.landscape.yml' warning: no previously-included files found matching 'pip/_vendor/Makefile' warning: no previously-included files found matching 'tox.ini' warning: no previously-included files found matching 'dev-requirements.txt' warning: no previously-included files found matching 'appveyor.yml' no previously-included directories found matching '.github' no previously-included directories found matching '.travis' no previously-included directories found matching 'docs/_build' no previously-included directories found matching 'contrib' no previously-included directories found matching 'tasks' no previously-included directories found matching 'tests' creating /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg Extracting pip-9.0.1-py2.7.egg to /Library/Python/2.7/site-packages Adding pip 9.0.1 to easy-install.pth file Installing pip script to /usr/local/bin Installing pip2.7 script to /usr/local/bin Installing pip2 script to /usr/local/bin Installed /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg Processing dependencies for pip Finished processing dependencies for pip ➜ ~ pip --version pip 9.0.1 from /Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7) ➜ ~ pip install awscli --upgrade --user Collecting awscli Downloading awscli-1.11.185-py2.py3-none-any.whl (1.2MB) 100% |████████████████████████████████| 1.2MB 1.1MB/s Collecting colorama\u003c=0.3.7,\u003e=0.2.5 (from awscli) Downloading colorama-0.3.7-py2.py3-none-any.whl Collecting s3transfer\u003c0.2.0,\u003e=0.1.9 (from awscli) Downloading s3transfer-0.1.11-py2.py3-none-any.whl (54kB) 100% |████████████████████████████████| 61kB 6.2MB/s Collecting botocore==1.7.43 (from awscli) Downloading botocore-1.7.43-py2.py3-none-any.whl (3.7MB) 100% |████████████████████████████████| 3.7MB 363kB/s Collecting docutils\u003e=0.10 (from awscli) Downloading docutils-0.14-py2-none-any.whl (543kB) 100% |████████████████████████████████| 552kB 2.4MB/s Collecting rsa\u003c=3.5.0,\u003e=3.1.2 (from awscli) Downloading rsa-3.4.2-py2.py3-none-any.whl (46kB) 100% |████████████████████████████████| 51kB 5.9MB/s Collecting PyYAML\u003c=3.12,\u003e=3.10 (from awscli) Downloading PyYAML-3.12.tar.gz (253kB) 100% |████████████████████████████████| 256kB 3.5MB/s Collecting futures\u003c4.0.0,\u003e=2.2.0; python_version == \"2.6\" or python_version == \"2.7\" (from s3transfer\u003c0.2.0,\u003e=0.1.9-\u003eawscli) Downloading futures-3.1.1-py2-none-any.whl Collecting jmespath\u003c1.0.0,\u003e=0.7.1 (from botocore==1.7.43-\u003eawscli) Downloading jmespath-0.9.3-py2.py3-none-any.whl Collecting python-dateutil\u003c3.0.0,\u003e=2.1 (from botocore==1.7.43-\u003eawscli) Downloading python_dateutil-2.6.1-py2.py3-none-any.whl (194kB) 100% |████████████████████████████████| 194kB 4.5MB/s Collecting pyasn1\u003e=0.1.3 (from rsa\u003c=3.5.0,\u003e=3.1.2-\u003eawscli) Downloading pyasn1-0.3.7-py2.py3-none-any.whl (63kB) 100% |████████████████████████████████| 71kB 7.8MB/s Collecting six\u003e=1.5 (from python-dateutil\u003c3.0.0,\u003e=2.1-\u003ebotocore==1.7.43-\u003eawscli) Downloading six-1.11.0-py2.py3-none-any.whl Installing collected packages: colorama, futures, jmespath, docutils, six, python-dateutil, botocore, s3transfer, pyasn1, rsa, PyYAML, awscli Running setup.py install for PyYAML ... done Successfully installed PyYAML-3.12 awscli-1.11.185 botocore-1.7.43 colorama-0.3.7 docutils-0.14 futures-3.1.1 jmespath-0.9.3 pyasn1-0.3.7 python-dateutil-2.6.1 rsa-3.4.2 s3transfer-0.1.11 six-1.11.0 ➜ ~ aws --version zsh: command not found: aws ➜ ~ sw_vers ProductName: Mac OS X ProductVersion: 10.13.1 BuildVersion: 17B48 This does not work.\n","title":"Install AWS CLI on Mac","type":"post"},{"content":"The purpose of this is to evaluate options and suggest possible approaches for handling the sensitive information in Git repositories such as database credentials, API credentials, passwords, keys, certificates etc. Joel asked this question a few weeks ago - this is part of Milos\u0026rsquo;s security awareness program.\nThe issue # Git repos store in cleartext all credentials, that may also be including PROD credentials.\nEverybody who clones the repository - every developer has access to this information that should have been shared only with the support team that has legitimate access to production.\nThis is especially sensitive when project includes external parties that are collaborating on the project (partner development companies or subcontractors).\nPrevious attempts to solve this # We have tried to address this in two ways with mixed success, using these approaches:\nExtracting the information from source code # The issue with this was necessity of manual steps on deployment, increased risk of human errors and more costly / fragile deployment process. Not only was this against the direction we wanted to go (DevOps and automation - towards continuous integration), it also removed version tracking and history from those critically important artifact\nUsing two repositories # In a nutshell, in addition to \u0026ldquo;full\u0026rdquo; repo with all files (including secret files), there was a copy of the repository (dev-repo), containing a subset of the commits that had those sensitive files removed from history and from current worktree.\nBecause of the way how Git internally works (the history is a tree of commits which are immutable), the dev-repo must always be a subset of full repo - all commits in dev-repo must eventually exist in full repo, but not the other way around.\nThe idea was that only the team lead / senior internal dev team would use the full repo, while everybody else would have access only to dev-repo.\nThe main difficulties of this were\nthis approach required a complex and fragile manual merge from two upstream repos Git does not really support the concept of keeping two remotes non-synchronized human error in pushing could cause leaking of sensitive info to dev-repo the sync-merge was manual and time intensive the sync-merge had to be repeated before each release it was initially very labour intensive / costly to set-up two repositories so that the above process worked OK it did not 100% solve the problem as part of the DEV team still had full access to all credentials Research # I spent some time googling what others facing same challenge do.\nSome of the relevant links:\nhttp://www.twinbit.it/en/blog/storing-sensitive-data-git-repository-using-git-crypt http://blog.arvidandersson.se/2013/06/10/credentials-in-git-repos https://help.github.com/articles/removing-sensitive-data-from-a-repository/ John Resig of Javascript fame - http://ejohn.org/blog/keeping-passwords-in-source-control/ https://developer.rackspace.com/blog/protecting-sensitive-information-from-appearing-in-public-repos/ https://www.agwa.name/projects/git-crypt/ https://github.com/moby/moby/issues/13490 - this is about Docker but still relevant There are two main approaches to the issue: # Exclude the secret information and deliver using different channel # Basically, our attempt #1. The methods used either special property file or environment variables.\nThe issues with this approach # it requires changes in the source code as the values need to be retrieved from the other channel (e.g. read from file or accessed from ENV) it does not address maintaining the history / changes of the sensitive information. The file needs to be delivered /managed somehow or the .bash_profile needs to be managed the code retrieving the secret info may have issues / does not work well in heterogenous environment (developers using Windows, Macs, PROD using Linux) Encryption # This approach encrypts some of the files and decrypts them only in target environments.\nRequirements for this to work OK are # small number of files encrypted the secret files for different environment must be separated by path - e.g. connection credentials for DEV or QA or UAT must be available without decrypting the PROD specific file it must work with our build systems (ant/Jenkins based) Challenges with this approach # we need to make sure that the PROD credentials get decrypted before or during the deployment process. This can be performed either on the build server (assuming that they are properly secured) or in the PROD environment encryption / decryption key management Suggested approach # I suggest looking into two possible directions\nReusing existing solution POC # Judging by the research, the promising approach seems to be open source project https://www.agwa.name/projects/git-crypt/\nWe need to do a proof of concept that will answer the following questions:\ndoes it work as described? is there any performance impact with repos ~ 1GB size? are there any issues with Bitbucket? what is the experience of the developer without key / without git-crypt when cloning the repo with protected files? can we easily extend the build workflow to add decryption? is there any issue with performing decryption from the PROD server (sysutil)? what is the key management logistic / process? POC of two independent repos with layered approach # This is a combination of removing the files (replacing with dummy credentials for PROD) and utilizing second - secret repository for protected resources.\nThe key features of the solution # We do use two independent repositories.\nThe main repo contains placeholders for the protected files and is available to developers. The second repo contains only protected files, unencrypted, in pathnames corresponding to file locations in the first repo. This secret repo is available only to support or secured build server.\nThe build on non-PROD environment will work as before - connectivity to PROD would be prevented by false / fake credentials\nThe build in PROD would use the main repo, clone the secret repo in the different place and superimpose / overwrite files\nThe idea is very similar to the layered file system Docker uses - implemented by physical copy.\nThe script that will perform the overwrite will be part of the secret repo and will expect parameter - path to the root of the main repository\nWhy this is better than what we tried before: # there is no complex and fragile manual merge-sync required no danger of cross-copying commits - both repos are maintained separately no key management overhead Next steps # review / feedback POC for git-crypt POC for layered repos decision implementation ","date":"May 17, 2017","externalUrl":null,"permalink":"/posts/2017-05-15-sensitive-git/","section":"Posts","summary":"The purpose of this is to evaluate options and suggest possible approaches for handling the sensitive information in Git repositories such as database credentials, API credentials, passwords, keys, certificates etc. Joel asked this question a few weeks ago - this is part of Milos’s security awareness program.\nThe issue # Git repos store in cleartext all credentials, that may also be including PROD credentials.\n","title":"Storing sensitive information in Git","type":"post"},{"content":"This is based on J.\u0026rsquo;s\u0026rsquo; question in Slack:\nDo we have some customer where we are moving a git repo to svn in an automated fashion I just need to move the git repo into svn periodically nightly\nThe setup (as I understand it):\non client side we have a worktree that is Git repository the files needs to be copied to SVN regularly Options # Use git-svn bridge # Git client allows to \u0026ldquo;pretend\u0026rdquo; it is SVN and pull/push against remote SVN repo\nThe documenation for this is here: https://git-scm.com/docs/git-svn\nThis would be the simplest option if it works and can be automated.\nCaveats # it depends on the upstream SVN server version and structure of the repository whether it works - I have seen issues with older SVN software, needs to be tested dcommit uses rebase internally which leads to changing SHA1 of the commits - not recommended if repository is part of the normal Gitflow git based development this works reasonably well for simple structures on SVN side (no or few branches) and not frequent merges on Git side (using rebase to linearize histories) Example # Tracking and contributing to the trunk of a Subversion-managed project (ignoring tags and branches):\n# Clone a repo (like git clone): git svn clone http://svn.example.com/project/trunk # Enter the newly cloned directory: cd trunk # You should be on master branch, double-check with \u0026#39;git branch\u0026#39; git branch # Do some work and commit locally to Git: git commit ... # Something is committed to SVN, rebase your local changes against the # latest changes in SVN: git svn rebase # Now commit your changes (that were committed previously using Git) to SVN, # as well as automatically updating your working HEAD: git svn dcommit # Append svn:ignore settings to the default Git exclude file: git svn show-ignore \u0026gt;\u0026gt; .git/info/exclude Tracking and contributing to an entire Subversion-managed project (complete with a trunk, tags and branches):\n# Clone a repo with standard SVN directory layout (like git clone): git svn clone http://svn.example.com/project --stdlayout --prefix svn/ # Or, if the repo uses a non-standard directory layout: git svn clone http://svn.example.com/project -T tr -b branch -t tag --prefix svn/ # View all branches and tags you have cloned: git branch -r # Create a new branch in SVN git svn branch waldo # Reset your master to trunk (or any other branch, replacing \u0026#39;trunk\u0026#39; # with the appropriate name): git reset --hard svn/trunk # You may only dcommit to one branch/tag/trunk at a time. The usage # of dcommit/rebase/show-ignore should be the same as above. Using two independent clients # Basically, the work tree is independently managed by SVN client that does not see content of .git directory (it is in .svnignore) and git client that sees everything, including the .svn/ directory.\nThe workflow functions well as long as there is no or little merging on Subversion side.\nWorkflow: # checkout code in SVN use Git for development / merging, normal pull/push Gitflow when is time to sync use SVN client to add new files and checkin all changes that are result of many Git commits / merges will appear as single commit in SVN =\u0026gt; it is same as if somebody would have edited the files manually without any Git present ","date":"May 10, 2017","externalUrl":null,"permalink":"/posts/2017-05-10-remote-svn/","section":"Posts","summary":"This is based on J.’s’ question in Slack:\nDo we have some customer where we are moving a git repo to svn in an automated fashion I just need to move the git repo into svn periodically nightly\nThe setup (as I understand it):\non client side we have a worktree that is Git repository the files needs to be copied to SVN regularly Options # Use git-svn bridge # Git client allows to “pretend” it is SVN and pull/push against remote SVN repo\n","title":"Managing code in remote SVN repo","type":"post"},{"content":"","date":"November 2, 2016","externalUrl":null,"permalink":"/tags/gitolite/","section":"Tags","summary":"","title":"Gitolite","type":"tags"},{"content":" Task # Transfer full Git history (all branches, tags, etc) to Bitbucket so that development can continue from there\nUser setup # List all keys in Gitolite must have access to Gitolite admin interface cd $ADMIN_HOME/pensieve/PRJ-admin/gitolite-admin ➜ gitolite-admin git:(master) ll keydir total 144K -rw-r--r-- 1 miro 401 Jun 29 2015 alter.pub -rw-r--r-- 1 miro 397 Jun 29 2015 codereview.pub -rw-r--r-- 1 miro 400 Apr 18 2016 hybris.pub -rw-r--r-- 1 miro 400 Apr 19 2016 hybris2.pub -rw-r----- 1 miro 398 Mar 30 2016 irae.pub ... DELETED ... -rw-r--r-- 1 miro 401 Jun 29 2015 miro.pub -rw-r--r-- 1 miro 411 Jun 29 2015 tkuser.jenkins0.pub -rw-r--r-- 1 miro 411 Jun 29 2015 tkuser.jenkins2.pub These will be split to 5 usergroups\nAdministrators (admin access) - all projects Developers - write access to all branches except master and develop, this project only Leads - write access to all branches, this project only Support - read only access - all projects Agents - read only access (jenkins etc) Bitbucket project creation # create project - PRJ create empty repository PRJ in this project create user groups: PRJ-developers PRJ-leads assign the access to repo Assign the branch privileges (master: leads only write, develop: write leads only, developers via PR)\nRepository transfer # The steps for actually moving the code - that work without loosing anything\nclean clone the repository (standard way) # git clone prj@pensieve.thinkwrap.com:prj.git prj-normal\nrun the statistics # cd prj-normal ➜ prj-normal git:(master) git branch -a | wc -l 892 ➜ prj-normal git:(master) git branch -r | wc -l 891 ➜ prj-normal git:(master) git rev-list --all --count 5527 ➜ prj-normal git:(master) git tag | wc -l 3 mirror clone the repo # cd .. git clone --mirror prj@pensieve.thinkwrap.com:prj.git prj-mirror Difference between normal and mirror clone # ➜ prj-normal git:(master) ll total 8.0K -rw-r--r-- 1 miro 1.6K Oct 31 17:01 Dockerfile -rw-r--r-- 1 miro 714 Oct 31 17:01 docker-compose.yml drwxr-xr-x 17 miro 578 Oct 31 17:01 prjbackoffice drwxr-xr-x 16 miro 544 Oct 31 17:01 prjcockpits drwxr-xr-x 21 miro 714 Oct 31 17:01 prjcore drwxr-xr-x 18 miro 612 Oct 31 17:01 prjctpayment drwxr-xr-x 18 miro 612 Oct 31 17:01 prjfacades drwxr-xr-x 16 miro 544 Oct 31 17:01 prjfulfilmentprocess drwxr-xr-x 19 miro 646 Oct 31 17:01 prjinitialdata drwxr-xr-x 19 miro 646 Oct 31 17:01 prjintegration drwxr-xr-x 15 miro 510 Oct 31 17:01 prjproject drwxr-xr-x 6 miro 204 Oct 31 17:01 prjsampledata drwxr-xr-x 17 miro 578 Oct 31 17:01 prjstorefront drwxr-xr-x 16 miro 544 Oct 31 17:01 prjtest drwxr-xr-x 20 miro 680 Oct 31 17:01 prjuserregistrationaddon drwxr-xr-x 11 miro 374 Oct 31 17:01 twdeploy drwxr-xr-x 17 miro 578 Oct 31 17:01 twvoucheraddon drwxr-xr-x 18 miro 612 Oct 31 17:01 twwishlistaddon ➜ prj-mirror git:(master) ll total 100K -rw-r--r-- 1 miro 23 Oct 31 17:10 HEAD -rw-r--r-- 1 miro 257 Nov 2 09:08 config -rw-r--r-- 1 miro 73 Oct 31 17:06 description drwxr-xr-x 11 miro 374 Oct 31 17:06 hooks drwxr-xr-x 3 miro 102 Oct 31 17:06 info drwxr-xr-x 4 miro 136 Oct 31 17:06 objects -rw-r--r-- 1 miro 88K Oct 31 17:10 packed-refs drwxr-xr-x 4 miro 136 Oct 31 17:06 refs ➜ prj-normal git:(master) git branch -a | tail -10 remotes/origin/release/1.21 remotes/origin/release/1.22 remotes/origin/release/1.3 remotes/origin/release/1.4 remotes/origin/release/1.5 remotes/origin/release/1.6 remotes/origin/release/1.7 remotes/origin/release/1.8 remotes/origin/release/1.9 remotes/origin/release/prj-UAT_2016-05-05 ➜ prj-mirror git:(master) git branch -a | tail -10 release/1.21 release/1.22 release/1.3 release/1.4 release/1.5 release/1.6 release/1.7 release/1.8 release/1.9 release/prj-UAT_2016-05-05 re-run the statistics # ➜ prj-mirror git:(master) git branch -a | wc -l 890 ➜ prj-mirror git:(master) git branch -r | wc -l 0 ➜ prj-mirror git:(master) git rev-list --all --count 5527 Explanation of the differences # mirror has no remote branches two missing branches are cd prj-normal; git branch -a \u0026gt;../prjbranch-norm; cd .. cd prj-mirror; git branch -a \u0026gt;../prjbranch-mirror; cd .. cat prjbranch-norm | sed \u0026#39;s!remotes/origin/!!\u0026#39; \u0026gt;prjbranch-norm2 diff -u prjbranch-norm2 prjbranch-mirror ➜ tmp diff -u prjbranch-norm2 prjbranch-mirror --- prjbranch-norm2 2016-10-31 17:24:14.000000000 +0100 +++ prjbranch-mirror 2016-10-31 17:23:25.000000000 +0100 @@ -1,6 +1,4 @@ -* master Cleanoverride - HEAD -\u0026gt; origin/master prjSTORE-1085-cart-update-message prjSTORE-1087-download-quantity prjSTORE-1142-unavailable-button-links @@ -865,7 +863,7 @@ hotfix/v2 hotfix/v3 hotfix/v4 - master +* master release/1.0 release/1.1 release/1.10 ➜ tmp Missing is local master branch and local reference HEAD pointing to master - this makes no sense for bare repository\nchange the upstream / upload\ngit remote set-url --push origin git@bitbucket.org:thinkwrap/prj.git git push --mirror RE-clone from Bitbucket # git clone git@bitbucket.org:thinkwrap/prj.git prj-bitbucket\nre-run the statistics # ➜ prj-mirror git:(master) cd ../prj-bitbucket ➜ prj-bitbucket git:(master) git branch -a | wc -l 892 ➜ prj-bitbucket git:(master) git branch -r | wc -l 891 ➜ prj-bitbucket git:(master) git rev-list --all --count 5527 ➜ prj-bitbucket git:(master) git tag | wc -l 3 compare # =\u0026gt; same number of commits, branches, tags etc\nAdd Gitolite users to Bitbucket # ask for BB account name assign to correct group ","date":"November 2, 2016","externalUrl":null,"permalink":"/posts/2016-11-02-pensieve-to-bitbucket/","section":"Posts","summary":"Task # Transfer full Git history (all branches, tags, etc) to Bitbucket so that development can continue from there\nUser setup # List all keys in Gitolite must have access to Gitolite admin interface cd $ADMIN_HOME/pensieve/PRJ-admin/gitolite-admin ➜ gitolite-admin git:(master) ll keydir total 144K -rw-r--r-- 1 miro 401 Jun 29 2015 alter.pub -rw-r--r-- 1 miro 397 Jun 29 2015 codereview.pub -rw-r--r-- 1 miro 400 Apr 18 2016 hybris.pub -rw-r--r-- 1 miro 400 Apr 19 2016 hybris2.pub -rw-r----- 1 miro 398 Mar 30 2016 irae.pub ... DELETED ... -rw-r--r-- 1 miro 401 Jun 29 2015 miro.pub -rw-r--r-- 1 miro 411 Jun 29 2015 tkuser.jenkins0.pub -rw-r--r-- 1 miro 411 Jun 29 2015 tkuser.jenkins2.pub These will be split to 5 usergroups\n","title":"Process for transferring Git repo from Gitolite to Bitbucket","type":"post"},{"content":" Update all local branches in Git repo # Issue: The git pull updates just one current branch.\nIn DevOps I am following many Git repos and need to keep up to date for all local branches.\ngit ffwd-update command # Source: http://stackoverflow.com/questions/4318161/can-git-pull-all-update-all-my-local-branches\nCreate file named git-ffwd-update somewhere on the path (in my case ~/bin)\n#!/bin/bash main() { REMOTES=\u0026#34;$@\u0026#34;; if [ -z \u0026#34;$REMOTES\u0026#34; ]; then REMOTES=$(git remote); fi REMOTES=$(echo \u0026#34;$REMOTES\u0026#34; | xargs -n1 echo) CLB=$(git branch -l|awk \u0026#39;/^\\*/{print $2}\u0026#39;); echo \u0026#34;$REMOTES\u0026#34; | while read REMOTE; do git remote update $REMOTE git remote show $REMOTE -n \\ | awk \u0026#39;/merges with remote/{print $5\u0026#34; \u0026#34;$1}\u0026#39; \\ | while read line; do RB=$(echo \u0026#34;$line\u0026#34;|cut -f1 -d\u0026#34; \u0026#34;); ARB=\u0026#34;refs/remotes/$REMOTE/$RB\u0026#34;; LB=$(echo \u0026#34;$line\u0026#34;|cut -f2 -d\u0026#34; \u0026#34;); ALB=\u0026#34;refs/heads/$LB\u0026#34;; NBEHIND=$(( $(git rev-list --count $ALB..$ARB 2\u0026gt;/dev/null) +0)); NAHEAD=$(( $(git rev-list --count $ARB..$ALB 2\u0026gt;/dev/null) +0)); if [ \u0026#34;$NBEHIND\u0026#34; -gt 0 ]; then if [ \u0026#34;$NAHEAD\u0026#34; -gt 0 ]; then echo \u0026#34; branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded\u0026#34;; elif [ \u0026#34;$LB\u0026#34; = \u0026#34;$CLB\u0026#34; ]; then echo \u0026#34; branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge\u0026#34;; git merge -q $ARB; else echo \u0026#34; branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. reseting local branch to remote\u0026#34;; git branch -l -f $LB -t $ARB \u0026gt;/dev/null; fi fi done done } main $@ Make sure the file is executable: chmod +x ~/bin/git-ffwd-update\nTest it out: # ➜ git:(develop) ✗ git ffwd-update Fetching origin remote: Counting objects: 2786, done. remote: Compressing objects: 100% (1385/1385), done. remote: Total 2786 (delta 1447), reused 2023 (delta 888) Receiving objects: 100% (2786/2786), 410.54 KiB | 0 bytes/s, done. Resolving deltas: 100% (1447/1447), completed with 141 local objects. From bitbucket.org:thinkwrap/XXXXXXX b060dd8..b72c54a develop -\u0026gt; origin/develop * [new branch] feature/FDPCare-5 -\u0026gt; origin/feature/FDPCare-5 f3f524c..3b7294e feature/STRIPES-1036 -\u0026gt; origin/feature/STRIPES-1036 * [new branch] feature/STRIPES-1079 -\u0026gt; origin/feature/STRIPES-1079 * [new branch] feature/STRIPES-1098-createPriceRowProductIdError -\u0026gt; origin/feature/STRIPES-1098-createPriceRowProductIdError * [new branch] feature/STRIPES-1104_sitemap_menu_items -\u0026gt; origin/feature/STRIPES-1104_sitemap_menu_items * [new branch] feature/STRIPES-1105_sitemap_pos -\u0026gt; origin/feature/STRIPES-1105_sitemap_pos * [new branch] feature/STRIPES-1106 -\u0026gt; origin/feature/STRIPES-1106 * [new branch] feature/STRIPES-1107 -\u0026gt; origin/feature/STRIPES-1107 * [new branch] feature/STRIPES-1108 -\u0026gt; origin/feature/STRIPES-1108 * [new branch] feature/STRIPES-1109 -\u0026gt; origin/feature/STRIPES-1109 * [new branch] feature/STRIPES-1112 -\u0026gt; origin/feature/STRIPES-1112 * [new branch] feature/STRIPES-1113 -\u0026gt; origin/feature/STRIPES-1113 * [new branch] feature/STRIPES-1114 -\u0026gt; origin/feature/STRIPES-1114 * [new branch] feature/STRIPES-1115 -\u0026gt; origin/feature/STRIPES-1115 * [new branch] feature/STRIPES-1116 -\u0026gt; origin/feature/STRIPES-1116 * [new branch] feature/STRIPES-1117 -\u0026gt; origin/feature/STRIPES-1117 * [new branch] feature/STRIPES-1124_Create_diagram_create_check -\u0026gt; origin/feature/STRIPES-1124_Create_diagram_create_check * [new branch] feature/STRIPES-1135_Controller_for_GMMS -\u0026gt; origin/feature/STRIPES-1135_Controller_for_GMMS * [new branch] feature/STRIPES-1140_autodiscount -\u0026gt; origin/feature/STRIPES-1140_autodiscount * [new branch] feature/STRIPES-1142 -\u0026gt; origin/feature/STRIPES-1142 * [new branch] feature/STRIPES-1143 -\u0026gt; origin/feature/STRIPES-1143 * [new branch] feature/STRIPES-1145_GMMS.stripesCodeCredit_facade -\u0026gt; origin/feature/STRIPES-1145_GMMS.stripesCodeCredit_facade * [new branch] feature/STRIPES-1149 -\u0026gt; origin/feature/STRIPES-1149 * [new branch] feature/STRIPES-1151 -\u0026gt; origin/feature/STRIPES-1151 * [new branch] feature/STRIPES-1152 -\u0026gt; origin/feature/STRIPES-1152 * [new branch] feature/STRIPES-1153 -\u0026gt; origin/feature/STRIPES-1153 * [new branch] feature/STRIPES-1154 -\u0026gt; origin/feature/STRIPES-1154 * [new branch] feature/STRIPES-1155 -\u0026gt; origin/feature/STRIPES-1155 * [new branch] hotfix/FDPCARE-72-2016-08-22 -\u0026gt; origin/hotfix/FDPCARE-72-2016-08-22 * [new branch] hotfix/STRIPES-1121-2016-08-18 -\u0026gt; origin/hotfix/STRIPES-1121-2016-08-18 * [new branch] hotfix/STRIPES-1133_on_side_issue -\u0026gt; origin/hotfix/STRIPES-1133_on_side_issue 0352331..c2bec59 master -\u0026gt; origin/master b4521ce..10a1d1d release/fdp-prod -\u0026gt; origin/release/fdp-prod * [new tag] 3.0.2(HF) -\u0026gt; 3.0.2(HF) * [new tag] release/FDP-PROD_2016-08-18 -\u0026gt; release/FDP-PROD_2016-08-18 * [new tag] release/FDP-PROD_2016-08-22-hotfix -\u0026gt; release/FDP-PROD_2016-08-22-hotfix * [new tag] release/FDP-UAT_2016-08-22-hotfix -\u0026gt; release/FDP-UAT_2016-08-22-hotfix * [new tag] 3.0.1(HF) -\u0026gt; 3.0.1(HF) * [new tag] release/FDP-PROD_2016-08-17 -\u0026gt; release/FDP-PROD_2016-08-17 * [new tag] release/FDP-UAT_2016-08-10 -\u0026gt; release/FDP-UAT_2016-08-10 * [new tag] release/FDP-UAT_2016-08-12 -\u0026gt; release/FDP-UAT_2016-08-12 * [new tag] release/FDP-UAT_2016-08-15 -\u0026gt; release/FDP-UAT_2016-08-15 * [new tag] release/FDP-UAT_2016-08-16 -\u0026gt; release/FDP-UAT_2016-08-16 branch develop was 216 commit(s) behind of origin/develop. fast-forward merge branch feature/STRIPES-79-maintain-code-compliance-jan-2016 was 87 commit(s) behind of origin/feature/STRIPES-79-maintain-code-compliance-jan-2016. reseting local branch to remote branch master was 1336 commit(s) behind of origin/master. reseting local branch to remote branch release/fdp-dev was 436 commit(s) behind of origin/release/fdp-dev. reseting local branch to remote branch release/fdp-prod was 447 commit(s) behind of origin/release/fdp-prod. reseting local branch to remote branch release/fdp-uat was 68 commit(s) behind of origin/release/fdp-uat. reseting local branch to remote branch release/livelab was 14 commit(s) behind of origin/release/livelab. reseting local branch to remote Automation for multiple repositories # Most of my repos are living under ~/src/CLIENTS. All except XYZ are accessed using ssh and public key\nCreate list of repos:\nREPOS=$(find . -type d -name \u0026#39;.git\u0026#39; | sed \u0026#39;s!/.git!/!\u0026#39;) echo $REPOS | grep -v XYZ \u0026gt;repos-list Edit the list if necessary.\nUse it to crawl\nfor i in $(cat repos-list); do cd $i; echo Processing $i; git ffwd-update; cd -; done\n","date":"September 5, 2016","externalUrl":null,"permalink":"/posts/2016-09-05-git-update-all-local-branches/","section":"Posts","summary":"Update all local branches in Git repo # Issue: The git pull updates just one current branch.\nIn DevOps I am following many Git repos and need to keep up to date for all local branches.\ngit ffwd-update command # Source: http://stackoverflow.com/questions/4318161/can-git-pull-all-update-all-my-local-branches\nCreate file named git-ffwd-update somewhere on the path (in my case ~/bin)\n","title":"Update all local branches in Git repo","type":"post"},{"content":"This quick summary to answer Megha Maiya\u0026rsquo;s question - I am adding to the Wiki in case it can be expanded later useful for somebody else:\nexpanded later useful for somebody else Free resources # There is HUGE amount of resources available for Linux and Unix out there. The issue is select those reasonably good\nList of lists: https://github.com/learnbyexample/scripting_course/blob/master/Linux_curated_resources.md http://ryanstutorials.net/, specially http://ryanstutorials.net/linuxtutorial/ and http://ryanstutorials.net/linuxtutorial/ http://www.tutorialspoint.com/unix/unix-getting-started.htm (bash scripting) - https://bash.cyberciti.biz/guide/Main_Page free book - http://unixmages.com/ufbm.pdf - very beginner friendly list of free books: http://www.dailyartisan.com/news/open-source-e-books-for-linux/ Eli The computer guy - https://www.youtube.com/playlist?list=PLD6B6473ACF32C59D (I like this one) YouTube channel - ultimate Linux tutorials - https://www.youtube.com/channel/UCn58SGUDUnUHRYKyNffHQrQ (from a generous Indian guy sharing his experience with the world for free. Not ideal audio quality, could use some editing - bot has lots of content) EDX courses - https://www.edx.org/school/linuxfoundationx http://www.tutorialspoint.com/listtutorials/linux/basic-concepts/1 Wikibooks - https://en.wikibooks.org/wiki/LPI_Linux_Certification Hands On # Reading books and watching videos will have very little impact without trying things out.\nI HIGHLY recommend\ninstall Virtualbox from Oracle (virtualbox.org) either create new virtual machine, download image and install Linux from scratch pick either Centos 6 or Centos 7 distribution or Ubuntu distribution or download ready-made VB image - http://www.osboxes.org/centos-7-image-virtualbox-vmware-available-x86_64/ and do a lot of practical exercises. The good free book covering installation is http://linux-training.be/linuxfun.pdf\nPaid resources # The advantage is that the content is usually better structured and easier to follow and also usually is targeting a certification exam.\nLinux Academy - $29/month - https://linuxacademy.com/tour - leads to certification Lynda - http://www.lynda.com/search?q=Linux, about $35/month, has 10 day free trial (RECOMMENDED) Cloud Academy - focusing more on AWS offering, ~ $50/month - https://cloudacademy.com/library/ Udemy - \u0026ldquo;pay by course\u0026rdquo; - https://www.udemy.com/courses/search/?ref=home\u0026src=ukw\u0026q=LInux\u0026lang=en Udacity - https://www.udacity.com/course/linux-command-line-basics--ud595 (some free courses) Sitepoint - lots of UI resources but also Linux. Good ebooks as part of membership: https://www.sitepoint.com/premium/topics/all?q=Linux\u0026amp;limit=24\u0026amp;offset=0\u0026amp;page=1\u0026amp;content_types[]=All\u0026amp;slugs[]=all\u0026amp;states[]=available\u0026amp;order= Non-Server side # As we discussed, no level of Linux system experience will help you if the Web app is having client side issues - broken JavaScript - and the request never reaches the server.\nTo get some experience with client-side browser based debugging try\nhttps://www.codeschool.com/courses/discover-devtools https://developer.chrome.com/devtools http://cs-server.usc.edu:45678/resources/tutorials/firebug-571.pdf http://getfirebug.com/wiki/index.php/Main_Page http://www.digitalmediaminute.com/screencast/firebug-js/ ","date":"May 30, 2016","externalUrl":null,"permalink":"/posts/2016-05-30-linux-resources/","section":"Posts","summary":"This quick summary to answer Megha Maiya’s question - I am adding to the Wiki in case it can be expanded later useful for somebody else:\nexpanded later useful for somebody else Free resources # There is HUGE amount of resources available for Linux and Unix out there. The issue is select those reasonably good\nList of lists: https://github.com/learnbyexample/scripting_course/blob/master/Linux_curated_resources.md http://ryanstutorials.net/, specially http://ryanstutorials.net/linuxtutorial/ and http://ryanstutorials.net/linuxtutorial/ http://www.tutorialspoint.com/unix/unix-getting-started.htm (bash scripting) - https://bash.cyberciti.biz/guide/Main_Page free book - http://unixmages.com/ufbm.pdf - very beginner friendly list of free books: http://www.dailyartisan.com/news/open-source-e-books-for-linux/ Eli The computer guy - https://www.youtube.com/playlist?list=PLD6B6473ACF32C59D (I like this one) YouTube channel - ultimate Linux tutorials - https://www.youtube.com/channel/UCn58SGUDUnUHRYKyNffHQrQ (from a generous Indian guy sharing his experience with the world for free. Not ideal audio quality, could use some editing - bot has lots of content) EDX courses - https://www.edx.org/school/linuxfoundationx http://www.tutorialspoint.com/listtutorials/linux/basic-concepts/1 Wikibooks - https://en.wikibooks.org/wiki/LPI_Linux_Certification Hands On # Reading books and watching videos will have very little impact without trying things out.\n","title":"Learning resources for Linux and Command line","type":"post"},{"content":"","date":"May 30, 2016","externalUrl":null,"permalink":"/tags/linux/","section":"Tags","summary":"","title":"Linux","type":"tags"},{"content":"I was intrigued by convenience of using Docker natively on Mac, without dealing with differences localhost != dockerhost, so I subscribed for Beta and installed it.\nGood news 1 # It can coexist with previous Docker installation (mostly) - see the note at the end. As long as you do not try to run native Docker and docker-machine at the same time, things coexist.\nGood news 2 # It works for several images I tried. And it is really convenient, seems to be faster (personal perception, not result of a measurement or a benchmark).\nNot so good news # Not ready for Hybris.\nI was trying to use Docker container for Oracle-XE to setup a PUQ environment (see Oracle DB on a Mac). The same container was run in native Docker and then in docker-machine setup.\nThe initialization in docker-machine succeeded.\nThe initialization in Native docker failed with network related errors:\nINFO | jvm 1 | main | 2016/05/17 09:47:01.156 | [m[0;31mERROR [ImpExWorker\u0026lt;2/4\u0026gt;] [][][] (junit) (00000000-ImpEx-Import) [ConnectionImpl] error resetting AutoCommit INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | [mjava.sql.SQLRecoverableException: Closed Connection INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at oracle.jdbc.driver.PhysicalConnection.setAutoCommit(PhysicalConnection.java:3711) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.jdbcwrapper.ConnectionImpl.doSetAutoCommit(ConnectionImpl.java:431) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.jdbcwrapper.ConnectionImpl.restoreAutoCommit(ConnectionImpl.java:185) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.jdbcwrapper.ConnectionImpl.unsetTxBound(ConnectionImpl.java:175) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | [0;31mERROR [ImpExWorker\u0026lt;2/4\u0026gt;] [][][] (junit) (00000000-ImpEx-Import) [Transaction] line 17 at main script: error rolling back transaction: Closed Connection INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | [mde.hybris.platform.tx.TransactionException: Closed Connection[VC:-1] INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | NESTED: java.sql.SQLRecoverableException: Closed Connection INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.toTransactionException(Transaction.java:819) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.rollbackOuter(Transaction.java:1080) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.rollback(Transaction.java:1028) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.finishExecute(Transaction.java:1238) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.execute(Transaction.java:1205) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.tx.Transaction.execute(Transaction.java:1160) INFO | jvm 1 | main | 2016/05/17 09:47:01.156 | at de.hybris.platform.impex.jalo.imp.DefaultImportProcessor.processInsertUpdateLine(DefaultImportProcessor.java:423) It would seem that native Docker, when under heavy load (as initialization does) starts closing connections.\nVersion mismatch after update # After stopping native docker, the docker-machine did not work:\n➜ platform docker-machine version docker-machine version 0.7.0, build a650a40 ➜ platform docker-machine start default Starting \u0026#34;default\u0026#34;... (default) Check network to re-create if needed... (default) Waiting for an IP... Machine \u0026#34;default\u0026#34; was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. ➜ platform docker-machine env export DOCKER_TLS_VERIFY=\u0026#34;1\u0026#34; export DOCKER_HOST=\u0026#34;tcp://192.168.99.100:2376\u0026#34; export DOCKER_CERT_PATH=\u0026#34;/Users/miro/.docker/machine/machines/default\u0026#34; export DOCKER_MACHINE_NAME=\u0026#34;default\u0026#34; # Run this command to configure your shell: # eval $(docker-machine env) ➜ platform eval $(docker-machine env) ➜ platform docker ps Error response from daemon: client is newer than server (client API version: 1.23, server API version: 1.22) Fix # Run docker-machine upgrade\n➜ platform docker-machine upgrade Waiting for SSH to be available... Detecting the provisioner... Upgrading docker... Stopping machine to do the upgrade... Upgrading machine \u0026#34;default\u0026#34;... Default Boot2Docker ISO is out-of-date, downloading the latest release... Latest release for github.com/boot2docker/boot2docker is v1.11.1 Downloading /Users/miro/.docker/machine/cache/boot2docker.iso from https://github.com/boot2docker/boot2docker/releases/download/v1.11.1/boot2docker.iso... 0%....10%....20%....30%....40%....50%....60%....70%....80%....90%....100% Copying /Users/miro/.docker/machine/cache/boot2docker.iso to /Users/miro/.docker/machine/machines/default/boot2docker.iso... Starting machine back up... (default) Check network to re-create if needed... (default) Waiting for an IP... Restarting docker... ➜ platform eval $(docker-machine env) ➜ platform docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ➜ platform docker run -d -p 2222:22 -p 1521:1521 -p 8080:8080 --name=oracle-xe alexeiled/docker-oracle-xe-11g b70600578607f57d179c887cc62d9503cdf39618296e831c857b6f67dc84917c ➜ platform docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b70600578607 alexeiled/docker-oracle-xe-11g \u0026#34;/bin/sh -c /start.sh\u0026#34; 5 seconds ago Up 4 seconds 0.0.0.0:1521-\u0026gt;1521/tcp, 0.0.0.0:8080-\u0026gt;8080/tcp, 0.0.0.0:2222-\u0026gt;22/tcp oracle-xe ➜ platform docker-machine version docker-machine version 0.7.0, build a650a40 ","date":"May 17, 2016","externalUrl":null,"permalink":"/posts/2016-05-17-docker-osx/","section":"Posts","summary":"I was intrigued by convenience of using Docker natively on Mac, without dealing with differences localhost != dockerhost, so I subscribed for Beta and installed it.\nGood news 1 # It can coexist with previous Docker installation (mostly) - see the note at the end. As long as you do not try to run native Docker and docker-machine at the same time, things coexist.\n","title":"Native OS-X Docker (Beta) - not quite there yet","type":"post"},{"content":"","date":"May 17, 2016","externalUrl":null,"permalink":"/tags/osx/","section":"Tags","summary":"","title":"Osx","type":"tags"},{"content":"Copy the installation of ACC for respective version from a Linux VM:\nThe startup script in bin/startClient will fail, because it cannot determine which Java to use to run the app.\nIt is trying to determine Unix flavour, failing that defaults to Solaris and ends up with invalid settings.\nFix # Set the variable JAVA_VM to path to executable command on your system.\nwhich java java is /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin/java java is /usr/bin/java export JAVA_VM=/Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin/java After that, it works.\nYou can also modify the script to make sure this happens automagically. I have commented out the Solaris default and replaced it with my Java\n","date":"March 24, 2016","externalUrl":null,"permalink":"/posts/2016-03-24-acc-on-osx/","section":"Posts","summary":"Copy the installation of ACC for respective version from a Linux VM:\nThe startup script in bin/startClient will fail, because it cannot determine which Java to use to run the app.\nIt is trying to determine Unix flavour, failing that defaults to Solaris and ends up with invalid settings.\nFix # Set the variable JAVA_VM to path to executable command on your system.\n","title":"Starting ACC (ATG Control Centre) on OS-X","type":"post"},{"content":"Using the Scala source repo to demonstrate - see Github\nShow merged and unmerged branches # This command allows you to show all local branches merged / unmerged to current branch\n➜ scala git:(2.12.x) git branch -a --merged * 2.12.x remotes/origin/2.11.x remotes/origin/2.12.x remotes/origin/HEAD -\u0026gt; origin/2.12.x ➜ scala git:(2.12.x) git branch -a --no-merged remotes/origin/2.10.x remotes/origin/2.8.x remotes/origin/2.9.x remotes/origin/DarkDimius-patch-1 remotes/origin/gh-pages remotes/origin/legacy/msil This shows you all local branches merged into named branch:\n➜ scala git:(2.12.x) git branch -a --merged origin/2.9.x remotes/origin/2.9.x Better output # Put these 2 lines into ~/.gitconfig under the \u0026lsquo;[alias]\u0026rsquo; section\nunmerged = !git branch -r --no-merged | grep -v HEAD | xargs -L1 git --no-pager log --pretty=tformat:\u0026#39;%Cgreen%d%Creset | %h | %an | %Cblue%ar%Creset\u0026#39; -1 | column -t -s \u0026#39;|\u0026#39; merged = !git branch -r --merged | grep -v HEAD | xargs -L1 git --no-pager log --pretty=tformat:\u0026#39;%Cgreen%d%Creset | %h | %an | %Cblue%ar%Creset\u0026#39; -1 | column -t -s \u0026#39;|\u0026#39; Here is how my alias section looks like\nThis is the output of the commands\n➜ scala git:(2.12.x) git unmerged fatal: Unknown commit master There are no local branches out of sync with master ➜ scala git:(2.12.x) git merged (origin/2.11.x) 1fcfdd8 Lukas Rytz 4 days ago (HEAD, origin/HEAD, origin/2.12.x, 2.12.x) 0e4c39a Vlad Ureche 2 days ago ","date":"March 23, 2016","externalUrl":null,"permalink":"/posts/2016-03-23-gitbits2/","section":"Posts","summary":"Using the Scala source repo to demonstrate - see Github\nShow merged and unmerged branches # This command allows you to show all local branches merged / unmerged to current branch\n➜ scala git:(2.12.x) git branch -a --merged * 2.12.x remotes/origin/2.11.x remotes/origin/2.12.x remotes/origin/HEAD -\u003e origin/2.12.x ➜ scala git:(2.12.x) git branch -a --no-merged remotes/origin/2.10.x remotes/origin/2.8.x remotes/origin/2.9.x remotes/origin/DarkDimius-patch-1 remotes/origin/gh-pages remotes/origin/legacy/msil This shows you all local branches merged into named branch:\n","title":"Git bits 2","type":"post"},{"content":"","date":"March 23, 2016","externalUrl":null,"permalink":"/tags/ruby/","section":"Tags","summary":"","title":"Ruby","type":"tags"},{"content":"This is Ruby script I found way back and was using it since.\nThe credits for creation goes to Zach Dennis. The script is decribed in his blog post\nThe source is here\nExample # This is beginning of very long output from Groovy source\nThe code # #!/usr/bin/env ruby require \u0026#39;rubygems\u0026#39; gem \u0026#39;term-ansicolor\u0026#39;, \u0026#39;\u0026gt;=1.0.5\u0026#39; require \u0026#39;term/ansicolor\u0026#39; class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:\u0026#34;%h %ad %an - %s\u0026#34; #{sha}~1..#{sha}` end def unmerged? content =~ /^\\+/ end def equivalent? content =~ /^\\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end # Returns origin from origin/some/branch/here def repository name.split(\u0026#34;/\u0026#34;, 2).first end # Returns some/branch/here from origin/some/branch/here def branch_name name.split(\u0026#34;/\u0026#34;, 2).last end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches \u0026lt; Array def self.clean_branch_output(str) str.split(/\\n/).map{ |e| e.strip.gsub(/\\*\\s+/, \u0026#39;\u0026#39;) }.reject{ |branch| branch =~ /\\b#{Regexp.escape(UPSTREAM)}\\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\\n/).map{ |c| GitCommit.new(c) } git_branches \u0026lt;\u0026lt; GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = \u0026#34;1.1\u0026#34; include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} @branches_to_prune = [] extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local =\u0026gt; local?, :remote =\u0026gt; remote?) @branches.reject!{|b| @options[:exclude].include?(b.name)} if @options[:exclude].is_a?(Array) @branches.select!{|b| @options[:only].include?(b.name)} if @options[:only].is_a?(Array) end def print_overview load if @options[:exclude] \u0026amp;\u0026amp; @options[:exclude].length \u0026gt; 0 puts \u0026#34;The following branches have been excluded\u0026#34; @options[:exclude].each do |branch_name| puts \u0026#34; #{branch_name}\u0026#34; end puts end if @options[:only] \u0026amp;\u0026amp; @options[:only].length \u0026gt; 0 puts \u0026#34;The following branches will be compared against:\u0026#34; @options[:only].each do |branch_name| puts \u0026#34; #{branch_name}\u0026#34; end puts end if branches.any_missing_commits? puts \u0026#34;The following branches possibly have commits not merged to #{upstream}:\u0026#34; branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts \u0026lt;\u0026lt;-EOT.gsub(/^\\s+\\|/, \u0026#39;\u0026#39;) |Usage: #{$0} [-a] [--upstream \u0026lt;branch\u0026gt;] [--remote] [--prune] | |This script wraps the \u0026#34;git cherry\u0026#34; command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow(\u0026#34;yellow\u0026#34;)} commits have not been merged | #{green(\u0026#34;green\u0026#34;)} commits have equivalent changes in \u0026lt;upstream\u0026gt; but different SHAs | |The default upstream is \u0026#39;master\u0026#39; (or \u0026#39;origin/master\u0026#39; if running with --remote) | |OPTIONS: | -a display all unmerged commits (verbose) | --remote (-r) compare remote branches instead of local branches | --upstream \u0026lt;branch\u0026gt; specify a specific upstream branch (defaults to master) | --exclude \u0026lt;branch\u0026gt;[,\u0026lt;branch\u0026gt;,...] specify a comma-separated list of branches to exclude | --only \u0026lt;branch\u0026gt;[,\u0026lt;branch\u0026gt;,...] specify a comma-separated list of branches to include | --prune prompts user to delete branches which have no differences with the upstream | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote (-r) | |EXAMPLE: delete branches without unmerged commits | #{$0} --prune | |EXAMPLE: delete remote branches without unmerged commits | #{$0} --remote --prune | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type \u0026#34;git unmerged\u0026#34; to use it. If you\u0026#39;d like to name | it something else and still refer to it with \u0026#34;git unmerged\u0026#34; then you\u0026#39;ll | need to set up an alias: | git config --global alias.unmerged \\\\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis \u0026lt;zdennis@mutuallyhuman.com\u0026gt; EOT exit end def print_version puts \u0026#34;#{VERSION}\u0026#34; end def branch_description local? ? \u0026#34;local\u0026#34; : \u0026#34;remote\u0026#34; end def print_specifics load if branches.any_missing_commits? print_breakdown else puts \u0026#34;There are no #{branch_description} branches out of sync with #{upstream}\u0026#34; end end def print_breakdown puts \u0026#34;Below is a breakdown for each branch. Here\u0026#39;s a legend:\u0026#34; puts print_legend branches.each do |branch| puts print \u0026#34;#{branch.name}:\u0026#34; if branch.unmerged_commits.empty? \u0026amp;\u0026amp; !show_equivalent_commits? print \u0026#34;(no unmerged commits\u0026#34; if prune? print \u0026#34;,\u0026#34;, red(\u0026#34; this will be pruned\u0026#34;) @branches_to_prune \u0026lt;\u0026lt; branch end print \u0026#34;)\\n\u0026#34; else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts \u0026#34; \u0026#34; + yellow(\u0026#34;yellow\u0026#34;) + \u0026#34; commits have not been merged\u0026#34; puts \u0026#34; \u0026#34; + green(\u0026#34;green\u0026#34;) + \u0026#34; commits have equivalent changes in #{UPSTREAM} but different SHAs\u0026#34; if show_equivalent_commits? end def prune return unless prune? if @branches_to_prune.empty? puts \u0026#34;\u0026#34;, \u0026#34;There are no branches to prune.\u0026#34; else # Protects Heroku repo\u0026#39;s rejected_master_branches = @branches_to_prune.reject!{|branch| branch.branch_name =~ /master/} puts \u0026#34;\u0026#34;, \u0026#34;Are you sure you want to prune the following #{@branches_to_prune.size} branches?\u0026#34;, \u0026#34;\u0026#34; puts red(\u0026#34;(Keep in mind this will remove these branches from the remote repository)\u0026#34;) if @remote @branches_to_prune.each do |branch| puts red(\u0026#34; #{branch.name}\u0026#34;) end puts \u0026#34;(omitting branches named master)\u0026#34; if rejected_master_branches puts print \u0026#34;y or n: \u0026#34; if STDIN.gets=~/y/i @branches_to_prune.each do |branch| if local? `git branch -D #{branch.name}` elsif remote? puts \u0026#34;pruning: #{branch.branch_name} with \u0026#39;git push #{branch.repository} :#{branch.branch_name}\u0026#39;\u0026#34; `git push #{branch.repository} :#{branch.branch_name}` end end puts \u0026#34;\u0026#34;, \u0026#34;Pruned #{@branches_to_prune.size} branches.\u0026#34; else puts \u0026#34;\u0026#34;, \u0026#34;Pruning aborted. All branches were left unharmed.\u0026#34; end end end def prune? ; @options[:prune ] ; end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? \u0026#34;master\u0026#34; elsif remote? \u0026#34;origin/master\u0026#34; end end private def extract_options_from_args(args) if args.include?(\u0026#34;--remote\u0026#34;) || args.include?(\u0026#34;-r\u0026#34;) @options[:remote] = true else @options[:local] = true end @options[:prune] = true if args.include?(\u0026#34;--prune\u0026#34;) @options[:show_help] = true if args.include?(\u0026#34;-h\u0026#34;) || args.include?(\u0026#34;--help\u0026#34;) @options[:show_equivalent_commits] = true if args.include?(\u0026#34;-a\u0026#34;) @options[:show_version] = true if args.include?(\u0026#34;-v\u0026#34;) || args.include?(\u0026#34;--version\u0026#34;) if index=args.index(\u0026#34;--upstream\u0026#34;) @options[:upstream] = args[index+1] end if index=args.index(\u0026#34;--exclude\u0026#34;) @options[:exclude] = args[index+1].split(\u0026#39;,\u0026#39;) end if index=args.index(\u0026#34;--only\u0026#34;) @options[:only] = args[index+1].split(\u0026#39;,\u0026#39;) end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics unmerged.prune end ","date":"March 22, 2016","externalUrl":null,"permalink":"/posts/2016-03-22-git-unmerged/","section":"Posts","summary":"This is Ruby script I found way back and was using it since.\nThe credits for creation goes to Zach Dennis. The script is decribed in his blog post\nThe source is here\nExample # This is beginning of very long output from Groovy source\nThe code # #!/usr/bin/env ruby require 'rubygems' gem 'term-ansicolor', '\u003e=1.0.5' require 'term/ansicolor' class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:\"%h %ad %an - %s\" #{sha}~1..#{sha}` end def unmerged? content =~ /^\\+/ end def equivalent? content =~ /^\\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end # Returns origin from origin/some/branch/here def repository name.split(\"/\", 2).first end # Returns some/branch/here from origin/some/branch/here def branch_name name.split(\"/\", 2).last end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches \u003c Array def self.clean_branch_output(str) str.split(/\\n/).map{ |e| e.strip.gsub(/\\*\\s+/, '') }.reject{ |branch| branch =~ /\\b#{Regexp.escape(UPSTREAM)}\\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\\n/).map{ |c| GitCommit.new(c) } git_branches \u003c\u003c GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = \"1.1\" include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} @branches_to_prune = [] extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local =\u003e local?, :remote =\u003e remote?) @branches.reject!{|b| @options[:exclude].include?(b.name)} if @options[:exclude].is_a?(Array) @branches.select!{|b| @options[:only].include?(b.name)} if @options[:only].is_a?(Array) end def print_overview load if @options[:exclude] \u0026\u0026 @options[:exclude].length \u003e 0 puts \"The following branches have been excluded\" @options[:exclude].each do |branch_name| puts \" #{branch_name}\" end puts end if @options[:only] \u0026\u0026 @options[:only].length \u003e 0 puts \"The following branches will be compared against:\" @options[:only].each do |branch_name| puts \" #{branch_name}\" end puts end if branches.any_missing_commits? puts \"The following branches possibly have commits not merged to #{upstream}:\" branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts \u003c\u003c-EOT.gsub(/^\\s+\\|/, '') |Usage: #{$0} [-a] [--upstream \u003cbranch\u003e] [--remote] [--prune] | |This script wraps the \"git cherry\" command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow(\"yellow\")} commits have not been merged | #{green(\"green\")} commits have equivalent changes in \u003cupstream\u003e but different SHAs | |The default upstream is 'master' (or 'origin/master' if running with --remote) | |OPTIONS: | -a display all unmerged commits (verbose) | --remote (-r) compare remote branches instead of local branches | --upstream \u003cbranch\u003e specify a specific upstream branch (defaults to master) | --exclude \u003cbranch\u003e[,\u003cbranch\u003e,...] specify a comma-separated list of branches to exclude | --only \u003cbranch\u003e[,\u003cbranch\u003e,...] specify a comma-separated list of branches to include | --prune prompts user to delete branches which have no differences with the upstream | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote (-r) | |EXAMPLE: delete branches without unmerged commits | #{$0} --prune | |EXAMPLE: delete remote branches without unmerged commits | #{$0} --remote --prune | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type \"git unmerged\" to use it. If you'd like to name | it something else and still refer to it with \"git unmerged\" then you'll | need to set up an alias: | git config --global alias.unmerged \\\\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis \u003czdennis@mutuallyhuman.com\u003e EOT exit end def print_version puts \"#{VERSION}\" end def branch_description local? ? \"local\" : \"remote\" end def print_specifics load if branches.any_missing_commits? print_breakdown else puts \"There are no #{branch_description} branches out of sync with #{upstream}\" end end def print_breakdown puts \"Below is a breakdown for each branch. Here's a legend:\" puts print_legend branches.each do |branch| puts print \"#{branch.name}:\" if branch.unmerged_commits.empty? \u0026\u0026 !show_equivalent_commits? print \"(no unmerged commits\" if prune? print \",\", red(\" this will be pruned\") @branches_to_prune \u003c\u003c branch end print \")\\n\" else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts \" \" + yellow(\"yellow\") + \" commits have not been merged\" puts \" \" + green(\"green\") + \" commits have equivalent changes in #{UPSTREAM} but different SHAs\" if show_equivalent_commits? end def prune return unless prune? if @branches_to_prune.empty? puts \"\", \"There are no branches to prune.\" else # Protects Heroku repo's rejected_master_branches = @branches_to_prune.reject!{|branch| branch.branch_name =~ /master/} puts \"\", \"Are you sure you want to prune the following #{@branches_to_prune.size} branches?\", \"\" puts red(\"(Keep in mind this will remove these branches from the remote repository)\") if @remote @branches_to_prune.each do |branch| puts red(\" #{branch.name}\") end puts \"(omitting branches named master)\" if rejected_master_branches puts print \"y or n: \" if STDIN.gets=~/y/i @branches_to_prune.each do |branch| if local? `git branch -D #{branch.name}` elsif remote? puts \"pruning: #{branch.branch_name} with 'git push #{branch.repository} :#{branch.branch_name}'\" `git push #{branch.repository} :#{branch.branch_name}` end end puts \"\", \"Pruned #{@branches_to_prune.size} branches.\" else puts \"\", \"Pruning aborted. All branches were left unharmed.\" end end end def prune? ; @options[:prune ] ; end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? \"master\" elsif remote? \"origin/master\" end end private def extract_options_from_args(args) if args.include?(\"--remote\") || args.include?(\"-r\") @options[:remote] = true else @options[:local] = true end @options[:prune] = true if args.include?(\"--prune\") @options[:show_help] = true if args.include?(\"-h\") || args.include?(\"--help\") @options[:show_equivalent_commits] = true if args.include?(\"-a\") @options[:show_version] = true if args.include?(\"-v\") || args.include?(\"--version\") if index=args.index(\"--upstream\") @options[:upstream] = args[index+1] end if index=args.index(\"--exclude\") @options[:exclude] = args[index+1].split(',') end if index=args.index(\"--only\") @options[:only] = args[index+1].split(',') end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics unmerged.prune end","title":"Git - find unmerged commits","type":"post"},{"content":"Git command git shortlog is very handy to see what is team activity.\nShow committer activity - whole project # (output shortened to first 20 lines)\ngit shortlog -sn | head -20 2991\tPaul King 1757\tCedric Champeau 1615\tJochen Theodorou 1031\tJames Strachan 749\tGuillaume Laforge 312\tRoshan Dawrani 306\tJason Dillon 301\tDanno Ferrin 284\tAlex Tkachman 273\tPascalSchumacher 230\tJohn Wilson 217\tPascal Schumacher 204\tpascalschumacher 160\tThibault Kruse 158\tJeremy Rayner 134\tRussel Winder 123\tCédric Champeau 122\tHamlet D\u0026#39;Arcy 116\tDierk Koenig 104\tPilho Kim variant (without n) has different ordering:\ngit shortlog -s | head -20 6\tAdrian Nistor 20\tAlan Green 1\tAlan Thompson 1\tAlessio Stalla 1\tAlex Spurling 284\tAlex Tkachman 24\tAlexandru Popescu 1\tAnders D. Johnson 79\tAndre Steingress 63\tAndres Almiray 8\tAndrew Eisenberg 6\tAndrew Hamilton 2\tAndrew Reitz 6\tAndrew Taylor 51\tAndrey Bloschetsov 1\tAndy Hamilton 1\tAndy Wilkinson 2\tAnto 12\tAseem Bansal 1\tAslak Hellesoy Full history with commits # git shortlog Adrian Nistor (6): avoiding wasted work according to GROOVY-5823 to GROOVY-5831, except GROOVY-5828 Signed-off-by: Jochen Theodorou \u0026lt;blackdrag@gmx.org\u0026gt; Fast exit from method ClassCompletionVerifier.checkMethodForWeakerAccessPrivileges Fast exit from loop in StaticTypeCheckingVisitor.inferReturnTypeGenerics Avoiding unnecessary string comparisons in loop GROOVY-5854: Fast loop exit in ClassNode constructor Inefficient method DefaultGrailsDomainClassInjector.implementsMethod Alan Green (20): Fix bug: was ignoring first char of octal escapes. Added asBool conversion for Strings: convert empty strings to false, and non-empty strings to true. Made AsmClassGenerator understand String asBool the same that Invoker has. Backed out fix to GROOVY-812 as it was causing test cases to fail. Will also post a note to groovy-dev. Fix build - UberTestCase could not find SpreadMapOperatorTest Changed to use jmock-1.0.1 instead of jmock-SNAPSHOT Fix for GROOVY-1081 Added Collection.sum() and Collection.sum(Closure) methods and test cases. Make it possible to set variables in the console shell bindings before the console is openned. Fix bug: could not add components to root pane with constraints. Now you can. Added history feature. Fixed problem when running from groovyConsole.bat Added special handling for showing collections and maps Fix problem with using BoxLayout on top level container (Frame, Dialog, Applet) Added new features to Console - intercepts std output - binds last result to \u0026#39;_\u0026#39; and history of results to \u0026#39;__\u0026#39; Fix error with bindings when creating a new window Changed is() to use == instead of System.identityHashCode() Console was reporting null result when result was [], \u0026#34;\u0026#34; or 0 Fix so that AssertionErrors are handled properly. Fixed SourceUnit.failedWithUnexpectedEOF() to correctly recognise incomplete source, allowing the InteractiveShell to be a bit more useful - GROOVY-472 and GROOVY-1021 Removed UnexpectedTokenException class as it does not appear to be used any longer. Alan Thompson (1): Fix a bug in JsonBuilder.toPrettyString() for zero-length strings. More interesting is when we restrict by branch\ngit shortlog -sn origin/GROOVY_1_5_X 137 Paul King 92 Jochen Theodorou 25 Roshan Dawrani 25 Jim White 23 Guillaume Laforge 14 Martin Kempf 9 Danno Ferrin 7 Alex Tkachman 5 Andres Almiray 4 Peter Niederwieser 2 Jeremy Rayner 2 Russel Winder 1 Jeff Brown 1 Thom Nichols And of course, it can be combined with other selection operators:\ngit shortlog --author=\u0026#34;graeme\u0026#34; --pretty=format:\u0026#34;%h %ad | %s%d [%an]\u0026#34; Graeme Rocher (2): 71dc762 Fri Aug 21 12:45:49 2015 +0200 | Improve StreamingJsonBuilder support for @CompileStatic [Graeme Rocher] 44d8e59 Tue Aug 25 16:57:45 2015 +0200 | Support for unescaped output in StreamingJsonBuilder [Graeme Rocher] graemerocher (6): de31d04 Tue Nov 3 16:05:33 2015 +0100 | Remove printlns that shouldn\u0026#39;t be there (closes #177) [graemerocher] 7e7fcf7 Wed Dec 2 11:13:25 2015 +0100 | Support for Array and Iterable not just Collection in StreamingJsonBuilder (closes #203) [graemerocher] f98e620 Wed Dec 2 11:49:02 2015 +0100 | Binary compatibility improvements [graemerocher] 2464f05 Wed Dec 9 14:06:20 2015 +0100 | GROOVY-7706 - StreamingJsonBuilder should handle nested closures (closes #208) [graemerocher] deb8395 Wed Dec 9 14:49:15 2015 +0100 | GROOVY-7708 - StreamingJsonBuilder - improve @CompileStatic support (closes #209) [graemerocher] 7f72540 Thu Dec 10 14:46:12 2015 +0100 | GROOVY-7707 - StreamingJsonBuilder - writing unescaped output doesn\u0026#39;t reset state (closes #210) [graemerocher] ","date":"March 21, 2016","externalUrl":null,"permalink":"/posts/2016-03-21-gitbits1/","section":"Posts","summary":"Git command git shortlog is very handy to see what is team activity.\nShow committer activity - whole project # (output shortened to first 20 lines)\ngit shortlog -sn | head -20 2991\tPaul King 1757\tCedric Champeau 1615\tJochen Theodorou 1031\tJames Strachan 749\tGuillaume Laforge 312\tRoshan Dawrani 306\tJason Dillon 301\tDanno Ferrin 284\tAlex Tkachman 273\tPascalSchumacher 230\tJohn Wilson 217\tPascal Schumacher 204\tpascalschumacher 160\tThibault Kruse 158\tJeremy Rayner 134\tRussel Winder 123\tCédric Champeau 122\tHamlet D'Arcy 116\tDierk Koenig 104\tPilho Kim variant (without n) has different ordering:\n","title":"Git committer activity","type":"post"},{"content":" Git project statistic tool # Python based, requires Python 2.6+\nWorks OOTB on Mac\nInstallation # Download TAR from Github unzipped to /opt ➜ ll /opt/gitinspector-0.3.2 total 52K -rw-r--r-- 1 miro 999 Jul 29 2013 DESCRIPTION.txt -rw-r--r-- 1 miro 32K Jun 14 2013 LICENSE.txt -rw-r--r-- 1 miro 78 Jul 2 2013 MANIFEST.in -rw-r--r-- 1 miro 681 Jan 13 2014 README.txt drwxr-xr-x 45 miro 1.5K Mar 20 2015 gitinspector -rw-r--r-- 1 miro 1.9K Jan 14 2014 setup.py -rw-r--r-- 1 miro 110 Jul 27 2013 stdeb.cfg create symlink from ~/bin (or from whatever directory on $PATH) ln -s /opt/gitinspector-0.3.2/gitinspector/gitinspector.py ~/bin/gitinspector.py ➜ ~ ll ~/bin | grep gitin lrwxr-xr-x 1 miro 52 Mar 20 16:06 gitinspector.py -\u0026gt; /opt/gitinspector-0.3.2/gitinspector/gitinspector.py Example # Look at scala sources - git@github.com:scala/scala.git\n➜ scala git:(2.12.x) gitinspector.py -Tlr --since=2014-01-01 The following historical commit information, by author, was found in the repository: Author Commits Insertions Deletions % of changes Adriaan Moors 6 69 7365 9.81 Antoine Gourlay 6 98 7391 9.88 David Hoepelman 1 30 25 0.07 EECOLOR 1 1 5 0.01 Eitan Adler 1 2 2 0.01 Felix Mulder 12 776 6272 9.30 Janek Bogucki 1 2 2 0.01 Jason Zaugg 26 617 263 1.16 Kato Kazuyoshi 3 12 12 0.03 Lukas Rytz 22 7400 44785 68.87 Marcin Kubala 1 95 35 0.17 Mariot Chauvin 1 6 29 0.05 Michał Pociecha 1 1 1 0.00 Pim Verkerk 1 1 1 0.00 Seth Tisue 1 0 38 0.05 Simon Ochsenreither 3 246 71 0.42 Viktor Klang 1 19 44 0.08 mpociecha 1 26 26 0.07 Below are the number of rows from each author that have survived and are still intact in the current revision: Author Rows % in comments Adriaan Moors 29 10.34 Antoine Gourlay 18 38.89 David Hoepelman 30 10.00 EECOLOR 1 0.00 Felix Mulder 616 11.36 Janek Bogucki 2 0.00 Jason Zaugg 430 8.84 Kato Kazuyoshi 5 0.00 Lukas Rytz 34620 1.20 Marcin Kubala 49 2.04 Pim Verkerk 1 0.00 Simon Ochsenreither 245 5.31 mpociecha 2 100.00 The following history timeline has been gathered from the repository: Author 2014-02 2014-03 2014-05 2014-06 2014-07 2014-08 2014-09 2014-10 2014-11 2014-12 2015-02 Adriaan Moors ++ - ----++++ Antoine Gourlay --------- +++++++++ Jason Zaugg +++++++++ + . +++++++++ +++++++++ . +++++++++ Kato Kazuyoshi . Lukas Rytz ++++++++ . ++ . Marcin Kubala --++++++ Simon Ochsenreither ++++ Viktor Klang ------++ mpociecha ----++++ Modified Rows: 95 174 4028 7 1 7414 91 94 10 54 4 Author 2015-03 2015-04 2015-05 2015-06 2015-07 2015-08 2015-09 2015-10 2015-11 2015-12 2016-01 Adriaan Moors ++ --------- Antoine Gourlay . ++++++++ EECOLOR . Eitan Adler . Felix Mulder ---+++++ --------- Janek Bogucki ----++++ Jason Zaugg +++++++ . . + . +++++++++ . Kato Kazuyoshi . . Lukas Rytz ++++++++ --------- --------- ++++++++ ++++ Mariot Chauvin . Michał Pociecha . Seth Tisue --------- Simon Ochsenreither . . Modified Rows: 642 12953 31781 62 10763 40 12 6 4 173 5694 Author 2016-02 2016-03 David Hoepelman + Felix Mulder ----++++ -+ Jason Zaugg --------- Lukas Rytz . Pim Verkerk . Modified Rows: 1255 411 The following repsonsibilties, by author, were found in the current revision of the repository (comments are exluded from the line count, if possible): Adriaan Moors is mostly responsible for: 12 test/files/pos/t9356/MyAnnotation.java 3 test/files/pos/t6169/Skinnable.java 3 test/files/pos/t6169/ExistIndir.java 3 test/files/pos/t6169/ExistF.java 3 test/files/pos/t6169/Exist.java 1 test/files/pos/t6169/Skin.java 1 test/files/pos/t6169/OP.java Antoine Gourlay is mostly responsible for: 8 test/files/pos/t9239/Usage.java 1 test/files/neg/t4851/J2.java 1 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js 1 spec/public/scripts/highlight.pack.js David Hoepelman is mostly responsible for: 27 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js EECOLOR is mostly responsible for: 1 src/library/scala/runtime/BoxesRunTime.java Felix Mulder is mostly responsible for: 395 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js 74 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js 49 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js 26 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/diagrams.js 1 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.panzoom.min.js 1 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/jquery.mousewheel.min.js Janek Bogucki is mostly responsible for: 1 src/library/scala/reflect/ScalaSignature.java 1 src/library/scala/reflect/ScalaLongSignature.java Jason Zaugg is mostly responsible for: 45 test/files/run/t7741a/GroovyInterfaceDump.java 45 test/files/run/t7741a/GroovyInterface$1Dump.java 43 src/library/scala/runtime/StructuralCallSite.java 29 src/library/scala/runtime/LambdaDeserialize.java 20 src/library/scala/runtime/SymbolLiteral.java 16 test/files/run/indy-via-macro-with-dynamic-args/Bootstrap.java 15 test/files/run/indy-via-macro/Bootstrap.java 12 test/files/run/t9268/Java.java 11 test/files/pos/t5165b/TestAnnotation_1.java 10 test/files/pos/t9393/NamedImpl_2.java Kato Kazuyoshi is mostly responsible for: 5 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js Lukas Rytz is mostly responsible for: 495 src/library/scala/runtime/java8/JFunction2.java 495 src/library/scala/runtime/java8/JFunction2$mcZJJ$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZJI$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZJD$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZIJ$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZII$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZID$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZDJ$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZDI$sp.java 495 src/library/scala/runtime/java8/JFunction2$mcZDD$sp.java Marcin Kubala is mostly responsible for: 47 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/template.js 1 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/index.js Pim Verkerk is mostly responsible for: 1 src/scaladoc/scala/tools/nsc/doc/html/resource/lib/scheduler.js Simon Ochsenreither is mostly responsible for: 117 spec/public/scripts/toc.js 55 spec/public/scripts/main.js 11 test/files/neg/t8700b/Baz_1.java 11 test/files/neg/t8700a/Baz.java 5 test/files/run/t4788/SAnnotation.java 5 test/files/run/t4788/RAnnotation.java 5 test/files/run/t4788/CAnnotation.java 5 test/files/run/t4788-separate-compilation/SAnnotation_1.java 5 test/files/run/t4788-separate-compilation/RAnnotation_1.java 5 test/files/run/t4788-separate-compilation/CAnnotation_1.java The extensions below were found in the repository history (extensions used during statistical analysis are marked): rtf number x-build conf 0-M0 txt check xml [java] scala res json html yml css bnd tmpl sbt latex bib [js] SAMPLE awk html5 properties md bat sha1 svg script list sh flags ","date":"March 20, 2016","externalUrl":null,"permalink":"/posts/2016-03-20-gitinspector/","section":"Posts","summary":"Git project statistic tool # Python based, requires Python 2.6+\nWorks OOTB on Mac\nInstallation # Download TAR from Github unzipped to /opt ➜ ll /opt/gitinspector-0.3.2 total 52K -rw-r--r-- 1 miro 999 Jul 29 2013 DESCRIPTION.txt -rw-r--r-- 1 miro 32K Jun 14 2013 LICENSE.txt -rw-r--r-- 1 miro 78 Jul 2 2013 MANIFEST.in -rw-r--r-- 1 miro 681 Jan 13 2014 README.txt drwxr-xr-x 45 miro 1.5K Mar 20 2015 gitinspector -rw-r--r-- 1 miro 1.9K Jan 14 2014 setup.py -rw-r--r-- 1 miro 110 Jul 27 2013 stdeb.cfg create symlink from ~/bin (or from whatever directory on $PATH) ln -s /opt/gitinspector-0.3.2/gitinspector/gitinspector.py ~/bin/gitinspector.py ➜ ~ ll ~/bin | grep gitin lrwxr-xr-x 1 miro 52 Mar 20 16:06 gitinspector.py -\u003e /opt/gitinspector-0.3.2/gitinspector/gitinspector.py Example # Look at scala sources - git@github.com:scala/scala.git\n","title":"Git project statistic tool","type":"post"},{"content":"I had to upgrade docker toolbox on Yosemite to get latest docker-compose additions.\nAfter installing the new package, I was not able to connect to docker machine:\n➜ ~ docker-machine status Stopped ➜ ~ docker-machine start default Starting \u0026#34;default\u0026#34;... (default) Check network to re-create if needed... (default) Waiting for an IP... Machine \u0026#34;default\u0026#34; was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. ➜ ~ docker-machine env default Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host \u0026#34;192.168.99.100:2376\u0026#34;: tls: DialWithDialer timed out You can attempt to regenerate them using \u0026#39;docker-machine regenerate-certs [name]\u0026#39;. Be advised that this will trigger a Docker daemon restart which will stop running containers. Regenerating the certificates did not solve the problem. Neither did reboot.\nTried\ndocker-machine --debug regenerate-certs -f default Fix # What worked for me was dropping and recreating the virtual machine Docker uses to run.\n➜ ~ docker-machine rm default About to remove default Are you sure? (y/n): y Successfully removed default ➜ ~ docker-machine create --driver virtualbox default Running pre-create checks... Creating machine... (default) Copying /Users/miro/.docker/machine/cache/boot2docker.iso to /Users/miro/.docker/machine/machines/default/boot2docker.iso... (default) Creating VirtualBox VM... (default) Creating SSH key... (default) Starting the VM... (default) Check network to re-create if needed... (default) Waiting for an IP... Waiting for machine to be running, this may take a few minutes... Detecting operating system of created instance... Waiting for SSH to be available... Detecting the provisioner... Provisioning with boot2docker... Copying certs to the local machine directory... Copying certs to the remote machine... Setting Docker configuration on the remote daemon... Checking connection to Docker... Docker is up and running! To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env default ➜ ~ docker-machine env default export DOCKER_TLS_VERIFY=\u0026#34;1\u0026#34; export DOCKER_HOST=\u0026#34;tcp://192.168.99.100:2376\u0026#34; export DOCKER_CERT_PATH=\u0026#34;/Users/miro/.docker/machine/machines/default\u0026#34; export DOCKER_MACHINE_NAME=\u0026#34;default\u0026#34; # Run this command to configure your shell: # eval $(docker-machine env default) ➜ ~ eval $(docker-machine env default) ➜ ~ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ➜ ~ docker images REPOSITORY TAG IMAGE ID CREATED SIZE Unfortunate (or fortunate ?) side effect is that all containers and images were blown away and I can start from scratch with lots of free disk space :-)\n","date":"March 16, 2016","externalUrl":null,"permalink":"/posts/2016-03-16-docker-machine-error-after-upgrade/","section":"Posts","summary":"I had to upgrade docker toolbox on Yosemite to get latest docker-compose additions.\nAfter installing the new package, I was not able to connect to docker machine:\n➜ ~ docker-machine status Stopped ➜ ~ docker-machine start default Starting \"default\"... (default) Check network to re-create if needed... (default) Waiting for an IP... Machine \"default\" was started. Waiting for SSH to be available... Detecting the provisioner... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. ➜ ~ docker-machine env default Error checking TLS connection: Error checking and/or regenerating the certs: There was an error validating certificates for host \"192.168.99.100:2376\": tls: DialWithDialer timed out You can attempt to regenerate them using 'docker-machine regenerate-certs [name]'. Be advised that this will trigger a Docker daemon restart which will stop running containers. Regenerating the certificates did not solve the problem. Neither did reboot.\n","title":"Fixing docker-machine error after upgrade","type":"post"},{"content":"Motivation for this hack is my unwillingness to suffer the pain of using Windows UI just to access BCC, ACC or other ATG tools requiring non command-line interface.\nThe credit for finding out about approach is blog post by James McOrmond - VPN over SSH - who is using this neat trick from Linux for quite some time.\nThe software mentioned https://github.com/apenwarr/sshuttle supposedly works on OS-X, however, it has not been updated for 4-5 years and would not function for me (OS-X Yosemite).\nThis version seems to work on 10.10 - but Homebrew is better anyway.\nFortunately, in the meantime somebody created brew cask, so to install functioning version run\nbrew install sshuttle How it works # Options available\n~ sshuttle error: at least one subnet, subnet file, or -N expected usage: sshuttle [-l [ip:]port] [-r [username@]sshserver[:port]] \u0026lt;subnets...\u0026gt; or: sshuttle --firewall \u0026lt;port\u0026gt; \u0026lt;subnets...\u0026gt; or: sshuttle --hostwatch -l, --listen ... transproxy to this ip address and port number -H, --auto-hosts scan for remote hostnames and update local /etc/hosts -N, --auto-nets automatically determine subnets to route --dns capture local DNS requests and forward to the remote DNS server --ns-hosts ... capture and forward remote DNS requests to the following servers --method ... auto, nat, tproxy or pf --python ... path to python interpreter on the remote server -r, --remote ... ssh hostname (and optional username) of remote sshuttle server -x, --exclude ... exclude this subnet (can be used more than once) -X, --exclude-from ... exclude the subnets in a file (whitespace separated) -v, --verbose increase debug message verbosity -e, --ssh-cmd ... the command to use to connect to the remote [ssh] --seed-hosts ... with -H, use these hostnames for initial scan (comma-separated) --no-latency-control sacrifice latency to improve bandwidth benchmarks --wrap ... restart counting channel numbers after this number (for testing) -D, --daemon run in the background as a daemon -s, --subnets ... file where the subnets are stored, instead of on the command line --syslog send log messages to syslog (default if you use --daemon) --pidfile ... pidfile name (only if using --daemon) [./sshuttle.pid] --server (internal use only) --firewall (internal use only) --hostwatch (internal use only) This is example from UAT environment in the clpud.\nThe externally visible box is uat-nat. If I ssh to this box, I am able to see the uat-mgmt box running BCC (which is otherwise inaccessible). I cannot however create ssh tunnel from uat-nat to uat-mgmt exposing 8080 port on mgmt, because this port would not be allowed for external access.\nInstead, I can use the sshuttle to direct all (or some) network traffic from local mac to the uat-nat box:\nsshuttle -vr miro.adamy@uat-nat 0/0 The -v flag means verbose - you will see the communication in the command line\nIt asks for 2 passwords:\nfirst, sudo password on local Mac then login password for the user on remote host (unless you have installed public key) After this, you can access the hosts inside AWS using internal IP address - e.g. access BCC on uat-mgmt :\nKeep in mind that only TCP and DNS is redirected, UDP, ICMP etc is not.\nOther useful tricks # Source: http://teohm.com/blog/2012/04/01/using-sshuttle-in-daily-work/\nRedirect the DNS as well # uses ssh_server from ~/.ssh/config\nsshuttle --dns -vr ssh_server 0/0 Exclude some traffic # sshuttle --dns -vr ssh_server -x 121.9.204.0/24 -x 61.135.196.21 0/0 Redirect ONLY some traffic # sshuttle -vr ssh_server 121.9.204.0/24 61.135.196.21 Few helpers # (after some search found at )\n# sshuttle helpers # set default SSH server: # user@hostname or a host in ~/.ssh/config TNL_SERVER=default_ssh # tunnel all traffic including DNS alias tnl=\u0026#34;sshuttle --dns -vr $TNL_SERVER 0/0\u0026#34; # returns a list of IP addresses from given domain(s). # # Examples: # dns2ip google.com # dns2ip netflix.com movies.netflix.com # function dns2ip() { dig +short $* | sed \u0026#34;/[^0-9\\.]/d\u0026#34; # use sed to remove non-IPv4 line e.g. alias } # tunnel specified domain(s) only. # # Examples: # tnlonly google.com # tnlonly netflix.com movies.netflix.com # function tnlonly() { sshuttle -vr $TNL_SERVER `dns2ip $*`; } # tunnel all traffic including DNS, except the specified domain(s). # # Examples: # tnlbut youku.com # tnlbut youku.com weibo.com # function tnlbut() { sshuttle --dns -vr $TNL_SERVER `dns2ip $* | sed \u0026#34;s/^/-x/\u0026#34;` 0/0; # use sed to append \u0026#39;-x\u0026#39; prefix } # vpn to a ssh server. # # Examples: # vpnto my_office_server # host in ~/.ssh/config # vpnto user@123.123.123.123 # function vpnto() { sshuttle -HNvr $1; } ","date":"February 18, 2016","externalUrl":null,"permalink":"/posts/2016-02-18-access-aws-servers/","section":"Posts","summary":"Motivation for this hack is my unwillingness to suffer the pain of using Windows UI just to access BCC, ACC or other ATG tools requiring non command-line interface.\nThe credit for finding out about approach is blog post by James McOrmond - VPN over SSH - who is using this neat trick from Linux for quite some time.\nThe software mentioned https://github.com/apenwarr/sshuttle supposedly works on OS-X, however, it has not been updated for 4-5 years and would not function for me (OS-X Yosemite).\n","title":"Accessing internal AWS servers directly from Mac","type":"post"},{"content":" p4merge as default file compare for PathFinder # Set the tool in File Comparison\nHow to use it # Select 2 files, right click, compare from context menu In dual mode, select one file on each side, compare ","date":"December 22, 2015","externalUrl":null,"permalink":"/posts/2015-12-22-p4merge/","section":"Posts","summary":"p4merge as default file compare for PathFinder # Set the tool in File Comparison\nHow to use it # Select 2 files, right click, compare from context menu In dual mode, select one file on each side, compare ","title":"p4merge as default file compare for PathFinder","type":"post"},{"content":" After the reboot # docker version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: darwin/amd64 Cannot connect to the Docker daemon. Is the docker daemon running on this host? ➜ gitolite-admin git:(master) docker-machine active No active host found ➜ gitolite-admin git:(master) docker-machine env default Error checking TLS connection: default is not running. Please start it in order to use the connection settings ➜ gitolite-admin git:(master) docker-machine start Error: Expected to get one or more machine names as arguments ➜ gitolite-admin git:(master) docker-machine start default (default) Starting VM... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. ➜ gitolite-admin git:(master) docker-machine env default export DOCKER_TLS_VERIFY=\u0026#34;1\u0026#34; export DOCKER_HOST=\u0026#34;tcp://192.168.99.100:2376\u0026#34; export DOCKER_CERT_PATH=\u0026#34;/Users/miro/.docker/machine/machines/default\u0026#34; export DOCKER_MACHINE_NAME=\u0026#34;default\u0026#34; # Run this command to configure your shell: # eval \u0026#34;$(docker-machine env default)\u0026#34; ➜ gitolite-admin git:(master) eval \u0026#34;$(docker-machine env default)\u0026#34; ➜ gitolite-admin git:(master) docker version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: darwin/amd64 Server: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: linux/amd64 Useful guide # See https://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide\n","date":"December 11, 2015","externalUrl":null,"permalink":"/posts/2015-12-11-docker-starting/","section":"Posts","summary":"After the reboot # docker version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: darwin/amd64 Cannot connect to the Docker daemon. Is the docker daemon running on this host? ➜ gitolite-admin git:(master) docker-machine active No active host found ➜ gitolite-admin git:(master) docker-machine env default Error checking TLS connection: default is not running. Please start it in order to use the connection settings ➜ gitolite-admin git:(master) docker-machine start Error: Expected to get one or more machine names as arguments ➜ gitolite-admin git:(master) docker-machine start default (default) Starting VM... Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command. ➜ gitolite-admin git:(master) docker-machine env default export DOCKER_TLS_VERIFY=\"1\" export DOCKER_HOST=\"tcp://192.168.99.100:2376\" export DOCKER_CERT_PATH=\"/Users/miro/.docker/machine/machines/default\" export DOCKER_MACHINE_NAME=\"default\" # Run this command to configure your shell: # eval \"$(docker-machine env default)\" ➜ gitolite-admin git:(master) eval \"$(docker-machine env default)\" ➜ gitolite-admin git:(master) docker version Client: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: darwin/amd64 Server: Version: 1.9.1 API version: 1.21 Go version: go1.4.3 Git commit: a34a1d5 Built: Fri Nov 20 17:56:04 UTC 2015 OS/Arch: linux/amd64 Useful guide # See https://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide\n","title":"Docker - getting started","type":"post"},{"content":"The ACC is installed in default location: ~/ATG/ACC11.1\nThis does not work OOTB. You must set 2 additional ENV properties\ncd ~/ATG/ACC11.0 export ACC_HOME=`pwd` export JAVA_VM=/usr/java/jdk1.7.0_51//bin/java bin/startClient \u0026amp; Starting from dyn/admin # The start in separate VM works OK.\nStart in server VM brings errors message very often complaining of malformed Help URL. The issue is documented here: http://stackoverflow.com/questions/20868244/how-to-fix-malformed-help-url-while-opening-acc-atg - for JBOSS.\nI tried to add the protocol.jar from DAS/lib into Tomcat lib, but it made no difference.\nWhat DOES help though is to create directory \u0026ldquo;endorsed\u0026rdquo; underneath $CATALINA_HOME and put the protocol.jar there:\nAfter this fix, the ACC starts clean in-server as well.\nWhat also helped (found out independently) was adding protocol.jar into lib directory of ACC\nNote # As soon as there are any custom classes in project, in order to open them, 2 things needs to happen\nthe classes.jar must be created (run ant jar) the MANIFEST.MF must contain download directive Manifest-Version: 1.0 ATG-Config-Path: config/ ATG-Required: DSS DPS ATG-Class-Path: classes/ testclasses/ lib/apache-commons/commons-lang-2.6.jar ATG-Client-Class-Path: lib/classes.jar ATG-Assembler-Import-File: true Name: lib/classes.jar ATG-Client-Update-File: true ATG-Client-Update-Version: 1.0 After this it works:\n","date":"July 15, 2015","externalUrl":null,"permalink":"/posts/2015-07-15-acc-in-vm/","section":"Posts","summary":"The ACC is installed in default location: ~/ATG/ACC11.1\nThis does not work OOTB. You must set 2 additional ENV properties\ncd ~/ATG/ACC11.0 export ACC_HOME=`pwd` export JAVA_VM=/usr/java/jdk1.7.0_51//bin/java bin/startClient \u0026 Starting from dyn/admin # The start in separate VM works OK.\nStart in server VM brings errors message very often complaining of malformed Help URL. The issue is documented here: http://stackoverflow.com/questions/20868244/how-to-fix-malformed-help-url-while-opening-acc-atg - for JBOSS.\n","title":"Starting ACC in VM","type":"post"},{"content":" The general idea # #!/bin/bash # Parameter: tag or sha1 git checkout --orphan temp $1 git commit -m \u0026#34;Truncated history\u0026#34; git rebase --onto temp $1 master git branch -D temp Requires Git 1.8+\nWorks well for mostly linear history (aka Git used for diff-ing of the catalog feeds).\nHow it works # Starting repo (training):\n➜ test git:(master) git last fe4e396 2015-07-13 | Fix for BuildInfo in TDD, database connectivity works (HEAD, origin/dynamovies/main, master) [Miro Adamy] f1b8636 2015-07-13 | Tables and database creation [Miro Adamy] d4c182b 2015-07-13 | Added template of dynamovies module - with empty UI. No database yet [Miro Adamy] f8df977 2015-07-13 | Enabling the Tomcat Manager (origin/d1-200/main) [Miro Adamy] 9f68fe9 2015-07-13 | Initial for Persons [Miro Adamy] 9bd92e3 2015-07-13 | BuildInfo returns String (tag: d1-160-end, origin/d1-160/main) [Miro Adamy] d319c11 2015-07-12 | Experimenting with remote debug [ATG Training VM 11.1] 4d06a1c 2015-07-12 | Fix for TDD integration, BuildInfo [ATG Training VM 11.1] af66abb 2015-07-12 | Added TDD + build works [ATG Training VM 11.1] 967e368 2015-07-12 | Added first source to test libraries [ATG Training VM 11.1] 83755b2 2015-07-12 | Libraries for Mac [Miro Adamy] b805361 2015-07-12 | Eclipse project + userlib [ATG Training VM 11.1] 13a0b1c 2015-07-12 | Cleaner Manifest (tag: d1-160-start, tag: d1-150-end, origin/d1-150/main) [ATG Training VM 11.1] 246dd9f 2015-07-11 | Better way how to create tables [Miro Adamy] 41c626f 2015-07-11 | Resolved tomcat issues on Mac [Miro Adamy] 59c55c2 2015-07-11 | Runnable configuration [ATG Training VM 11.1] f3649e6 2015-07-11 | Fixed dependencies (tag: d1-150-start, tag: d1-140-end, origin/d1-140/main) [ATG Training VM 11.1] 9007415 2015-07-11 | No classes.jar yet [ATG Training VM 11.1] 6d45bf5 2015-07-11 | Removed web modules, using DCS [ATG Training VM 11.1] 3acbc08 2015-07-11 | Introduced module structure - template [ATG Training VM 11.1] 365ce26 2015-07-11 | Fixed the table creation for usage counter (tag: d1-140-start, origin/master, origin/HEAD) [ATG Training VM 11.1] e01305e 2015-07-11 | Added skeleton [ATG Training VM 11.1] 1672624 2015-07-11 | New module [ATG Training VM 11.1] How it looks\nWe will cut it off at commit d4c182b\ngit checkout --orphan temp d4c182b This creates \u0026ldquo;unconnected\u0026rdquo; branch \u0026rsquo;temp\u0026rsquo; starting from the named commit and prepared this state for initial commit:\n➜ test git:(master) git checkout --orphan temp d4c182b Switched to a new branch \u0026#39;temp\u0026#39; ➜ test git:(temp) ✗ git status On branch temp Initial commit Changes to be committed: (use \u0026#34;git rm --cached \u0026lt;file\u0026gt;...\u0026#34; to unstage) new file: .gitignore new file: .project new file: META-INF/MANIFEST.MF new file: TDD/.classpath new file: TDD/.gitignore new file: TDD/.project new file: TDD/META-INF/MANIFEST.MF new file: TDD/Notes.txt new file: TDD/build.bat new file: TDD/build.properties new file: TDD/build.sh new file: TDD/build.xml new file: TDD/config/CONFIG.properties ... Deleted ... ➜ test git:(temp) ✗ git commit -m \u0026#34;Truncated history\u0026#34; [temp (root-commit) 5eaf635] Truncated history 214 files changed, 17643 insertions(+) create mode 100644 .gitignore create mode 100644 .project create mode 100644 META-INF/MANIFEST.MF create mode 100644 TDD/.classpath create mode 100755 TDD/.gitignore create mode 100644 TDD/.project create mode 100644 TDD/META-INF/MANIFEST.MF create mode 100644 TDD/Notes.txt create mode 100644 TDD/build.bat create mode 100644 TDD/build.properties create mode 100755 TDD/build.sh create mode 100644 TDD/build.xml create mode 100644 TDD/config/CONFIG.properties ...Deleted ... ➜ test git:(temp) git last 5eaf635 2015-07-14 | Truncated history (HEAD, temp) [Miro Adamy] We have now two unconnected lines of history:\nNext step is to copy all commits after the starting one onto new line:\n➜ test git:(temp) git rebase --onto temp d4c182b master First, rewinding head to replay your work on top of it... Applying: Tables and database creation Applying: Fix for BuildInfo in TDD, database connectivity works ➜ test git:(master) git last 92a19bb 2015-07-13 | Fix for BuildInfo in TDD, database connectivity works (HEAD, master) [Miro Adamy] 9dd9267 2015-07-13 | Tables and database creation [Miro Adamy] 5eaf635 2015-07-14 | Truncated history (temp) [Miro Adamy] Now we are on master but it is really short:\nNow we can delete temp and invoke GC\ngit branch -D temp git gc # We can do even better git repack -Ad ","date":"July 14, 2015","externalUrl":null,"permalink":"/posts/2015-15-07-git-history/","section":"Posts","summary":"The general idea # #!/bin/bash # Parameter: tag or sha1 git checkout --orphan temp $1 git commit -m \"Truncated history\" git rebase --onto temp $1 master git branch -D temp Requires Git 1.8+\nWorks well for mostly linear history (aka Git used for diff-ing of the catalog feeds).\nHow it works # Starting repo (training):\n","title":"How to truncate Git history","type":"post"},{"content":"","date":"July 12, 2015","externalUrl":null,"permalink":"/tags/dynadmin/","section":"Tags","summary":"","title":"Dynadmin","type":"tags"},{"content":" How to get information about all ATG Nucleus components # Dyn Admin has useful feature - Configuration reporter: http://localhost:8080/dyn/admin/atg/dynamo/admin/en/config-reporter-property-representation1.jhtml\nThere are two variations of the report: Property representation report - PRR (shorter version) and Bean representation report (BRR). The PRR does not report properties that have default values, while BRR is reporting current values of all properties. Compare the sizes\n-rw-r--r-- 1 miro 2.2M Jul 12 14:07 bean1 -rw-r--r-- 1 miro 2.5M Jul 12 14:07 bean1.xml -rw-r--r-- 1 miro 275K Jul 12 13:50 file1 -rw-r--r-- 1 miro 572K Jul 12 13:51 file1.xml In both cases first creates binary file with properties and then transforms it to XML format:\nBoth files will be saved in the home directory of the JVM.\nIn development, it will be most likely the ATG module directory - from where the Start script was run.\nYou can format it\nxmllint \u0026ndash;format file1.xml \u0026gt;file1-formatted.xml\nafter which it looks like this (PRR)\n... \u0026lt;/component\u0026gt; \u0026lt;component NAME=\u0026#34;/atg/devtools/ArchiveDirectoryCache\u0026#34;\u0026gt; \u0026lt;property NAME=\u0026#34;$scope\u0026#34;\u0026gt;\u0026lt;![CDATA[global]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;directoryAgent\u0026#34;\u0026gt;\u0026lt;![CDATA[./ContainerAppDirectoryAgent]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logListeners\u0026#34;\u0026gt;\u0026lt;![CDATA[atg/dynamo/service/logging/LogQueue,atg/dynamo/service/logging/ScreenLog]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;schedule\u0026#34;\u0026gt;\u0026lt;![CDATA[every 30 minutes]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;stagingDirectoryRoot\u0026#34;\u0026gt;\u0026lt;![CDATA[{serverHomeDirResource?resourceURI=j2ee/archive-cache}]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;$description\u0026#34;\u0026gt;\u0026lt;![CDATA[server-side J2EE application and stand alone archived application cache]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingWarning\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logging.logListeners\u0026#34;\u0026gt;\u0026lt;![CDATA[atg/dynamo/service/logging/LogQueue,atg/dynamo/service/logging/ScreenLog]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;$class\u0026#34;\u0026gt;\u0026lt;![CDATA[atg.ui.j2edit.model.CachingJ2eeArchiveDirectoryAgent]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingError\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingDebug\u0026#34;\u0026gt;\u0026lt;![CDATA[false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;enabled^\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/Configuration.j2eeArchiveCachingEnabled]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;scheduler\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/Scheduler]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component NAME=\u0026#34;/atg/devtools/ComponentIndex\u0026#34;\u0026gt; \u0026lt;property NAME=\u0026#34;logging.logListeners\u0026#34;\u0026gt;\u0026lt;![CDATA[atg/dynamo/service/logging/LogQueue,atg/dynamo/service/logging/ScreenLog]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingWarning\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingDebug\u0026#34;\u0026gt;\u0026lt;![CDATA[false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;moduleManager\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/modules/ModuleManager]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;excludeDirectories\u0026#34;\u0026gt;\u0026lt;![CDATA[/docroot,/atg/dynamo/servlet/sessiontracking/SessionManager,/atg/dynamo/servlet/pipeline/RequestScopeManager,/atg/reporting/contentviewed,/atg/reporting/profilegroup,/atg/reporting/requests,/atg/reporting/userevents]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;componentIndexFile\u0026#34;\u0026gt;\u0026lt;![CDATA[{serverHomeDirResource?resourceURI=data/componentIndex.ser}]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;$description\u0026#34;\u0026gt;\u0026lt;![CDATA[Index of all configured global components in Nucleus]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logListeners\u0026#34;\u0026gt;\u0026lt;![CDATA[atg/dynamo/service/logging/LogQueue,atg/dynamo/service/logging/ScreenLog]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingError\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;componentManager\u0026#34;\u0026gt;\u0026lt;![CDATA[ComponentManager]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;$class\u0026#34;\u0026gt;\u0026lt;![CDATA[atg.ui.component.model.GlobalComponentIndex]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component NAME=\u0026#34;/atg/devtools/ComponentManager\u0026#34;\u0026gt; \u0026lt;property NAME=\u0026#34;loggingDebug\u0026#34;\u0026gt;\u0026lt;![CDATA[false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingError\u0026#34;\u0026gt;\u0026lt;![CDATA[true]]\u0026gt;\u0026lt;/property\u0026gt; ... or this (BRR):\n... \u0026lt;/component\u0026gt; \u0026lt;component NAME=\u0026#34;/atg/devtools/ArchiveDirectoryCache\u0026#34;\u0026gt; \u0026lt;property NAME=\u0026#34;schedule\u0026#34;\u0026gt;\u0026lt;![CDATA[schedule every 30 minutes without catch up]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingTrace\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingTrace false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;adminServlet\u0026#34;\u0026gt;\u0026lt;![CDATA[adminServlet atg.nucleus.GenericService$1AdminServlet@5d6142fe]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingWarning\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingWarning true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingDebug\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingDebug false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;nucleus\u0026#34;\u0026gt;\u0026lt;![CDATA[nucleus /]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;scheduler\u0026#34;\u0026gt;\u0026lt;![CDATA[scheduler /atg/dynamo/service/Scheduler]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;absoluteName\u0026#34;\u0026gt;\u0026lt;![CDATA[absoluteName /atg/devtools/ArchiveDirectoryCache]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;serviceConfiguration\u0026#34;\u0026gt;\u0026lt;![CDATA[serviceConfiguration atg.nucleus.PropertyConfiguration@1c756197]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;enabled\u0026#34;\u0026gt;\u0026lt;![CDATA[enabled true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;purgeInterval\u0026#34;\u0026gt;\u0026lt;![CDATA[purgeInterval 4]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;nameContext\u0026#34;\u0026gt;\u0026lt;![CDATA[nameContext /atg/devtools]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;stagingDirectoryRoot\u0026#34;\u0026gt;\u0026lt;![CDATA[stagingDirectoryRoot /Users/miro/src/TRAINING/twc-training2/servers/atg/training_dev01/j2ee/archive-cache]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logListenerCount\u0026#34;\u0026gt;\u0026lt;![CDATA[logListenerCount 2]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;running\u0026#34;\u0026gt;\u0026lt;![CDATA[running true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingInfo true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;adminServletUseServletOutputStream\u0026#34;\u0026gt;\u0026lt;![CDATA[adminServletUseServletOutputStream false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;j2eeAppInfoCache\u0026#34;\u0026gt;\u0026lt;![CDATA[j2eeAppInfoCache {/Users/miro/ATG/ATG11.1/PubPortlet/:PubPortlets.ear=atg.ui.j2edit.model.J2eeAppInfo@3f9e8e2f, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669459-30/:screenscraper=atg.ui.j2edit.model.J2eeAppInfo@4288d04a, /Users/miro/ATG/ATG11.1/Tomcat/apache-tomcat-7.0.37/webapps/:host-manager=atg.ui.j2edit.model.J2eeAppInfo@2422cc66, /Users/miro/ATG/ATG11.1/ATGDBSetup/j2ee-apps/:ATGDBSetup=atg.ui.j2edit.model.J2eeAppInfo@68994f12, /Users/miro/ATG/ATG11.1/Service11.1/Service/CRMIntegration/j2ee-apps/:getAgentPasswordHashAlgorithm.ear=atg.ui.j2edit.model.J2eeAppInfo@29165c64, /Users/miro/ATG/ATG11.1/twc-training/servers/tomcat/training_dev01/webapps/:dyn=atg.ui.j2edit.model.J2eeAppInfo@7b0bbe4e, /Users/miro/ATG/ATG11.1/WSRP/admin/:admin=atg.ui.j2edit.model.J2eeAppInfo@3ffb31fe, /Users/miro/ATG/ATG11.1/Portal/gear-template/helloworld_war/:helloworld.war=atg.ui.j2edit.model.J2eeAppInfo@48f3b83, /Users/miro/ATG/ATG11.1/TWC-TDD/j2ee-apps/:TDD.ear=atg.ui.j2edit.model.J2eeAppInfo@578c17cb, /Users/miro/ATG/ATG11.1/WSRP/producer/:producer=atg.ui.j2edit.model.J2eeAppInfo@2e6e3d54, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669406-28/:quicklinks=atg.ui.j2edit.model.J2eeAppInfo@477c6d9c, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669177-22/:exchange=atg.ui.j2edit.model.J2eeAppInfo@3a00416e, /Users/miro/ATG/ATG11.1/DCS-UI/Versioned/j2ee-apps/:DCS-UI-Versioned.ear=atg.ui.j2edit.model.J2eeAppInfo@66c7ba81, /Users/miro/ATG/ATG11.1/Service11.1/Service/CRMIntegration/j2ee-apps/:loginAgentUser.ear=atg.ui.j2edit.model.J2eeAppInfo@42a59fde, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676667174-7/:Fcc=atg.ui.j2edit.model.J2eeAppInfo@7a2ca01, /Users/miro/ATG/ATG11.1/twc-training/servers/tomcat/training_dev01/webapps/:dyn#admin=atg.ui.j2edit.model.J2eeAppInfo@507c0b91, /Users/miro/ATG/ATG11.1/BIZUI/j2ee-apps/:bizui.ear=atg.ui.j2edit.model.J2eeAppInfo@7fdb85de, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676668997-14/:alert=atg.ui.j2edit.model.J2eeAppInfo@2531f366, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669691-37/:xmlprotocol=atg.ui.j2edit.model.J2eeAppInfo@7262c09d, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669036-16/:bookmarks=atg.ui.j2edit.model.J2eeAppInfo@3153be16, /Users/miro/ATG/ATG11.1/Portal/slotgear/:slotgear-war=atg.ui.j2edit.model.J2eeAppInfo@70e4afa6, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676667067-4/:atg-bootstrap=atg.ui.j2edit.model.J2eeAppInfo@35c7f531, /Users/miro/ATG/ATG11.1/DPS-UI/j2ee-apps/:DPS-UI.ear=atg.ui.j2edit.model.J2eeAppInfo@5ab27f8c, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676666956-0/:orderapproval=atg.ui.j2edit.model.J2eeAppInfo@7cd3eed8, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669537-33/:soapclient=atg.ui.j2edit.model.J2eeAppInfo@3de5e6ee, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669140-21/:docexch=atg.ui.j2edit.model.J2eeAppInfo@409c3301, /Users/miro/ATG/ATG11.1/twc-training/servers/atg/training_dev01/j2ee/archive-cache/1436676669302-26/:settings=atg.ui.j2edit.model.J2eeAppInfo@4ed8a7ca, /Users/miro/ATG/ATG11.1/ContentMgmt-UI/j2ee-apps/:ContentMgmt-UI.ear=atg.ui.j2edit.model.J2eeAppInfo@71e [DELETED the rest of line ...] \u0026lt;property NAME=\u0026#34;name\u0026#34;\u0026gt;\u0026lt;![CDATA[name ArchiveDirectoryCache]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logListeners\u0026#34;\u0026gt;\u0026lt;![CDATA[atg.service.configurationreporter.MultiValueProperty@76711470]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;serviceInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[serviceInfo server-side J2EE application and stand alone archived application cache]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;root\u0026#34;\u0026gt;\u0026lt;![CDATA[root /]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;cache\u0026#34;\u0026gt;\u0026lt;![CDATA[cache {}]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;adminServletOutputStreamEncoding\u0026#34;\u0026gt;\u0026lt;![CDATA[adminServletOutputStreamEncoding UTF-8]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingError\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingError true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;class\u0026#34;\u0026gt;\u0026lt;![CDATA[class class atg.ui.j2edit.model.CachingJ2eeArchiveDirectoryAgent]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;directoryAgent\u0026#34;\u0026gt;\u0026lt;![CDATA[directoryAgent /atg/devtools/ContainerAppDirectoryAgent]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;/component\u0026gt; \u0026lt;component NAME=\u0026#34;/atg/devtools/ComponentIndex\u0026#34;\u0026gt; \u0026lt;property NAME=\u0026#34;loggingTrace\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingTrace false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;adminServlet\u0026#34;\u0026gt;\u0026lt;![CDATA[adminServlet atg.nucleus.GenericService$1AdminServlet@1a9a8c3d]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingWarning\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingWarning true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingDebug\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingDebug false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;nucleus\u0026#34;\u0026gt;\u0026lt;![CDATA[nucleus /]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;absoluteName\u0026#34;\u0026gt;\u0026lt;![CDATA[absoluteName /atg/devtools/ComponentIndex]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;serviceConfiguration\u0026#34;\u0026gt;\u0026lt;![CDATA[serviceConfiguration atg.nucleus.PropertyConfiguration@186d0670]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;componentIndexFile\u0026#34;\u0026gt;\u0026lt;![CDATA[componentIndexFile /Users/miro/src/TRAINING/twc-training2/servers/atg/training_dev01/data/componentIndex.ser]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;enabled\u0026#34;\u0026gt;\u0026lt;![CDATA[enabled true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;excludeDirectories\u0026#34;\u0026gt;\u0026lt;![CDATA[atg.service.configurationreporter.MultiValueProperty@79f501cf]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;moduleManager\u0026#34;\u0026gt;\u0026lt;![CDATA[moduleManager /atg/modules/ModuleManager]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;rebuilding\u0026#34;\u0026gt;\u0026lt;![CDATA[rebuilding false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;nameContext\u0026#34;\u0026gt;\u0026lt;![CDATA[nameContext /atg/devtools]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;logListenerCount\u0026#34;\u0026gt;\u0026lt;![CDATA[logListenerCount 2]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;indexAvailable\u0026#34;\u0026gt;\u0026lt;![CDATA[indexAvailable false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;running\u0026#34;\u0026gt;\u0026lt;![CDATA[running true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;loggingInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[loggingInfo true]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;adminServletUseServletOutputStream\u0026#34;\u0026gt;\u0026lt;![CDATA[adminServletUseServletOutputStream false]]\u0026gt;\u0026lt;/property\u0026gt; \u0026lt;property NAME=\u0026#34;name\u0026#34;\u0026gt;\u0026lt;![CDATA[name ComponentIndex]]\u0026gt;\u0026lt;/property\u0026gt; The BRR file seems to have syntactic issues:\n➜ dev01 git:(d1-150/main) ✗ xmllint --format bean1.xml bean1.xml:10865: parser error : Char 0x0 out of allowed range 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ bean1.xml:10865: parser error : CData section not finished jmDNS ---- Services ----- Service: wanderlust.l 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ bean1.xml:10865: parser error : Premature end of data in tag property line 10852 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ bean1.xml:10865: parser error : Premature end of data in tag component line 10845 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ bean1.xml:10865: parser error : Premature end of data in tag component_list line 95 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ bean1.xml:10865: parser error : Premature end of data in tag repository line 1 14:10:9f:1f:cd:04@fe80::1610:9fff:fe1f:cd04._apple-mobdev._tcp.local.,4500/4279, ^ This offers very useful posibilities for using standard Unix text tools.\nFor example: list all components using other components:\ngrep -n \u0026#39;/atg/dynamo/service/jdbc/JTDataSource\u0026#39; file1-formatted.xml 255: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 1205: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 1344: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 1854: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 2335: \u0026lt;component NAME=\u0026#34;/atg/dynamo/service/jdbc/JTDataSource\u0026#34;\u0026gt; 2370: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 5497: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 6229: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 6489: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 6536: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 6815: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 6833: \u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[/atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; grep -n \u0026#39;/atg/dynamo/service/jdbc/JTDataSource\u0026#39; bean1.xml 785:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 7397:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 7756:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 9027:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 10605:\u0026lt;component NAME=\u0026#34;/atg/dynamo/service/jdbc/JTDataSource\u0026#34;\u0026gt; 10649:\u0026lt;property NAME=\u0026#34;absoluteName\u0026#34;\u0026gt;\u0026lt;![CDATA[absoluteName /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 10732:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 19875:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 20312:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 20460:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 20608:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 30639:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 31097:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 31340:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 32131:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; 32279:\u0026lt;property NAME=\u0026#34;dataSource\u0026#34;\u0026gt;\u0026lt;![CDATA[dataSource /atg/dynamo/service/jdbc/JTDataSource]]\u0026gt;\u0026lt;/property\u0026gt; Custom report # This allows possibility to report only part of hierarchy. You have to provide control file (complete hierarchy can be generated at\nhttp://localhost:8080/dyn/admin/atg/dynamo/admin/en/config-reporter-output-hierarchy-titled.jhtml?_DARGS=/atg/dynamo/admin/en/config-reporter-output-hierarchy-titled.jhtml.2\u0026_dynSessConf=-8731147233557828105\nThe file is not XML file, it contains lines for components and directories:\n... \u0026lt;component\u0026gt;/atg/userprofiling/RepositoryItemGroupRoleCacheAdapter\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ProfileTools\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/UserCacheAdapter\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/PageEventTrigger\u0026lt;/component\u0026gt; \u0026lt;directory\u0026gt;/atg/userprofiling/email\u0026lt;/directory\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/HtmlContentProcessor\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/TemplateEmailPersister\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/BatchEmailPeriodicService\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/TemplateEmailSender\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/TemplateEmailBatchPersister\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/email/TemplateEmailBatchServerPersister\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ProfileRequestServlet\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/FolderCacheAdapter\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ProfileUserDirectoryProperties\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/PropertyManager\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ProfileSessionFailServiceSharable\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/FolderPathCache\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ProfileItemFinder\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/DPSMessageSource\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/CookieManager\u0026lt;/component\u0026gt; \u0026lt;component\u0026gt;/atg/userprofiling/ExpiredPasswordService\u0026lt;/component\u0026gt; ... I have generated file, left only sub-tree of \u0026lsquo;/atg/userprofiling\u0026rsquo;:\nThis file is then used as input. If you leave file in the directory it was generated in, that is the safest way how it will be found.\nHere is the output:\n-rw-r--r-- 1 miro 146K Jul 12 14:28 bean2 -rw-r--r-- 1 miro 198K Jul 12 14:29 bean2.xml Weakness and issues # This tool would be much more useful if many important classes provided override \u0026rsquo;toString\u0026rsquo; methods.\nFor example, this is what you get from ProfileAdapterRepository\u0026rsquo;s DatabaseTableInfo\n... \u0026lt;property NAME=\u0026#34;databaseTableInfo\u0026#34;\u0026gt;\u0026lt;![CDATA[databaseTableInfo atg.adapter.gsa.DatabaseTableInfo@74924b8c]]\u0026gt;\u0026lt;/property\u0026gt; ","date":"July 12, 2015","externalUrl":null,"permalink":"/posts/2015-07-12-component-report/","section":"Posts","summary":"How to get information about all ATG Nucleus components # Dyn Admin has useful feature - Configuration reporter: http://localhost:8080/dyn/admin/atg/dynamo/admin/en/config-reporter-property-representation1.jhtml\nThere are two variations of the report: Property representation report - PRR (shorter version) and Bean representation report (BRR). The PRR does not report properties that have default values, while BRR is reporting current values of all properties. Compare the sizes\n","title":"How to get information about all ATG components","type":"post"},{"content":"This is mainly for Linux and Mac as they do not have good client.\nIt requires relatively modern Perl - 5.1x should work. I have\n➜ ~ perl --version This is perl 5, version 18, subversion 2 (v5.18.2) built for darwin-thread-multi-2level (with 2 registered patches, see perl -V for more detail) Get the kpcli distribution Download from Sourceforge - http://sourceforge.net/projects/kpcli/ or get the attached script kpcli-3.0.pl\nMake it executable and put it on the path:\nmv ~/Downloads/kpcli-3.0.pl ~/bin chmod +x ~/bin/kpcli-3.0.pl It will not work out of the box unless you install few Perl modules.\nEasiest way is to use cpanm, which is installed using cpan\n# Run CPAN and let it configure itself if run for the first time cpan # install cpanm using cpan sudo cpan App::cpanminus Now we can use cpanm to proceed\nsudo cpanm Crypt::Rijndael sudo cpanm Sort::Naturally sudo cpanm Term::ShellUI sudo cpanm File::KeePass # I had issues with Readline::Gnu sudo cpanm Term::ReadLine::Gnu # so I installed Perl5 version instead sudo cpanm Term::ReadLine::Perl5 sudo cpanm Clipboard sudo cpanm Capture:Tiny sudo cpanm Capture::Tiny ~/bin/kpcli-3.0.pl --help Now it can be run and open file. After opening you can navigate in the password file as in file system (try pwd, cd, ls) and copy password to clipboard (try h)\n➜ Sites git:(master) ✗ ~/bin/kpcli-3.0.pl --kdb ~/PASSWORDS/PAL.kdbx Please provide the master password: ************************* KeePass CLI (kpcli-3.0) v3.0 is ready for operation. Type \u0026#39;help\u0026#39; for a description of available commands. Type \u0026#39;help \u0026lt;command\u0026gt;\u0026#39; for details on individual commands. * NOTE: You are using Term::ReadLine::Perl5. Term::ReadLine::Gnu will provide better functionality. kpcli-3.0:/\u0026gt; ls === Groups === PAL-Keypass/ kpcli-3.0:/\u0026gt; h attach -- Manage attachments: attach \u0026lt;path to entry|entry number\u0026gt; cd -- Change directory (path to a group) cl -- Change directory and list entries (cd+ls) clone -- Clone an entry: clone \u0026lt;path to entry\u0026gt; \u0026lt;path to new entry\u0026gt; close -- Close the currently opened database cls -- Clear screen (\u0026#34;clear\u0026#34; command also works) copy -- Copy an entry: copy \u0026lt;path to entry\u0026gt; \u0026lt;path to new entry\u0026gt; edit -- Edit an entry: edit \u0026lt;path to entry|entry number\u0026gt; export -- Export entries to a new KeePass DB (export \u0026lt;file.kdb\u0026gt; [\u0026lt;file.key\u0026gt;]) find -- Finds entries by Title help -- Print helpful information history -- Prints the command history icons -- Change group or entry icons in the database import -- Import a password database (import \u0026lt;file\u0026gt; \u0026lt;path\u0026gt; [\u0026lt;file.key\u0026gt;]) ls -- Lists items in the pwd or specified paths (\u0026#34;dir\u0026#34; also works) mkdir -- Create a new group (mkdir \u0026lt;group_name\u0026gt;) mv -- Move an item: mv \u0026lt;path to a group|or entries\u0026gt; \u0026lt;path to group\u0026gt; new -- Create a new entry: new \u0026lt;optional path\u0026amp;|title\u0026gt; open -- Open a KeePass database file (open \u0026lt;file.kdb\u0026gt; [\u0026lt;file.key\u0026gt;]) pwck -- Check password quality: pwck \u0026lt;entry|group\u0026gt; pwd -- Print the current working directory quit -- Quit this program (EOF and exit also work) rename -- Rename a group: rename \u0026lt;path to group\u0026gt; rm -- Remove an entry: rm \u0026lt;path to entry|entry number\u0026gt; rmdir -- Delete a group (rmdir \u0026lt;group_name\u0026gt;) save -- Save the database to disk saveas -- Save to a specific filename (saveas \u0026lt;file.kdb\u0026gt; [\u0026lt;file.key\u0026gt;]) show -- Show an entry: show [-f] [-a] \u0026lt;entry path|entry number\u0026gt; stats -- Prints statistics about the open KeePass file ver -- Print the version of this program vers -- Same as \u0026#34;ver -v\u0026#34; xp -- Copy password to clipboard: xp \u0026lt;entry path|number\u0026gt; xu -- Copy username to clipboard: xu \u0026lt;entry path|number\u0026gt; xw -- Copy URL (www) to clipboard: xw \u0026lt;entry path|number\u0026gt; xx -- Clear the clipboard: xx Type \u0026#34;help \u0026lt;command\u0026gt;\u0026#34; for more detailed help on a command. kpcli-3.0:/\u0026gt; Enjoy\n","date":"July 8, 2015","externalUrl":null,"permalink":"/posts/2015-07-08-keepass-cli/","section":"Posts","summary":"This is mainly for Linux and Mac as they do not have good client.\nIt requires relatively modern Perl - 5.1x should work. I have\n➜ ~ perl --version This is perl 5, version 18, subversion 2 (v5.18.2) built for darwin-thread-multi-2level (with 2 registered patches, see perl -V for more detail) Get the kpcli distribution Download from Sourceforge - http://sourceforge.net/projects/kpcli/ or get the attached script kpcli-3.0.pl\nMake it executable and put it on the path:\n","title":"Accessing Keepass information from command line","type":"post"},{"content":"","date":"July 8, 2015","externalUrl":null,"permalink":"/tags/keepass/","section":"Tags","summary":"","title":"Keepass","type":"tags"},{"content":"","date":"July 8, 2015","externalUrl":null,"permalink":"/tags/perl/","section":"Tags","summary":"","title":"Perl","type":"tags"},{"content":"See\nSetting up a local web server on OS X 10.9 \u0026ldquo;Mavericks\u0026rdquo; Setting up a local web server on OS X 10.10 \u0026ldquo;Yosemite\u0026rdquo; Meta-List\nhttps://discussions.apple.com/docs/DOC-3083\n","date":"July 7, 2015","externalUrl":null,"permalink":"/posts/2015-07-07-osx-web/","section":"Posts","summary":"See\nSetting up a local web server on OS X 10.9 “Mavericks” Setting up a local web server on OS X 10.10 “Yosemite” Meta-List\nhttps://discussions.apple.com/docs/DOC-3083\n","title":"Setting up a local web server on a Mac","type":"post"},{"content":" Symptoms: # build fails cannot checkout / connect to GIT Validate this is the case # ssh to jenkins2 assume identity of jenkins user (VERY IMPORTANT) go to /home/projects/workspace/PROJECTNAME directory This directory is repository clone. Try \u0026lsquo;git status\u0026rsquo; in that directory. If you see something like\n-bash-3.2$ git status fatal: unable to read tree 2d0456480112e9f9a8508bb47dc3863112cc6253 the git repo is corrupted and needs to be reloaded.\nStep 1 - Get the remote repo URL # -bash-3.2$ git remote -v origin client@pensieve.thinkwrap.com:client-store.git (fetch) origin client@pensieve.thinkwrap.com:client-store.git (push) Step 2 - Clone the repo to /tmp location # -bash-3.2$ git clone client@pensieve.thinkwrap.com:client-store.git /tmp/client-store Cloning into /tmp/client-store... remote: Counting objects: 129011, done. remote: Compressing objects: 100% (36403/36403), done. remote: Total 129011 (delta 80801), reused 124811 (delta 77481) Receiving objects: 100% (129011/129011), 250.76 MiB | 30.13 MiB/s, done. Resolving deltas: 100% (80801/80801), done. The directory you clone into must not exist\nStep 3 - Erase corrupted \u0026lsquo;.git\u0026rsquo; repo # -bash-3.2$ pwd /home/projects/workspace/PROJECTNAME -bash-3.2$ rm -rf .git/ Step 4 - move the fresly cloned \u0026lsquo;.git\u0026rsquo; directory # We will steal the \u0026lsquo;.git\u0026rsquo; from the clone in /tmp/DIR\n-bash-3.2$ mv /tmp/client-store/.git .\nStep 5 - resynchronize \u0026lsquo;.git\u0026rsquo; and file tree # It is important to make sure that file tree does not have any modifications against the \u0026lsquo;.git\u0026rsquo;.\nSimplest way is:\n-bash-3.2$ git status # On branch master # Changes not staged for commit: # (use \u0026#34;git add/rm \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) # (use \u0026#34;git checkout -- \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) # # modified: Store/config/client/integration/ups/UpsConfiguration.properties # modified: Store/config/client/integration/ups/UpsManager.properties # deleted: Store/config/client/ui/droplet/ShippingEstimateDroplet.properties # modified: Store/j2ee/Store.war/css/theme.css # modified: Store/src/com/client/integrations/ups/UpsConfiguration.java # modified: Store/src/com/client/integrations/ups/UpsGateway.java # modified: Store/src/com/client/integrations/ups/UpsManager.java # modified: Store/src/com/client/integrations/ups/UpsRequestFactory.java # deleted: Store/src/com/client/ui/ShippingEstimate.java # deleted: Store/src/com/client/ui/droplet/ShippingEstimateDroplet.java # deleted: WRFulfillment/src/com/client/fcc/formatter/AdditionalItemFeedGenerator.java # deleted: WRFulfillment/src/com/client/fcc/formatter/ElectronicGiftCardItemFeedGenerator.java # deleted: WRFulfillment/src/com/client/fcc/formatter/OrderDetailFeedGenerator.java # deleted: WRFulfillment/src/com/client/fcc/formatter/OrderHeaderFeedGenerator.java # modified: servers/wool-prod-mgmt/localconfig/client/feeds/images/ImagesImportScheduler.properties # modified: servers/wool-prod-mgmt/localconfig/client/feeds/images/ImagesImportService.properties # # Untracked files: # (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to include in what will be committed) # # target/ no changes added to commit (use \u0026#34;git add\u0026#34; and/or \u0026#34;git commit -a\u0026#34;) As you see, this one does. We will blow it away. We are on branch master and use hard reset to remove all changes.\n-bash-3.2$ git reset --hard HEAD HEAD is now at 0a7f6c9 Client-824: Error handling -bash-3.2$ git pull Already up-to-date. Now there are no local changes.\nIf your task is using different branch - that does not matter because Jenkins is using checkouts using absolute sha-1 anyway and as long there are no local modifications that would prevent this checkout it will work.\n","date":"June 18, 2015","externalUrl":null,"permalink":"/posts/2015-06-18-jenkins-git/","section":"Posts","summary":"Symptoms: # build fails cannot checkout / connect to GIT Validate this is the case # ssh to jenkins2 assume identity of jenkins user (VERY IMPORTANT) go to /home/projects/workspace/PROJECTNAME directory This directory is repository clone. Try ‘git status’ in that directory. If you see something like\n","title":"How to fix Jenkins build issues related to Git connectivity","type":"post"},{"content":"","date":"June 18, 2015","externalUrl":null,"permalink":"/tags/jenkins/","section":"Tags","summary":"","title":"Jenkins","type":"tags"},{"content":"After re-creating the SSH key, I got the above error from Gitolite.\nFull trace:\n➜ TWC ssh -v thinkwrap@pensieve.thinkwrap.com OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Connecting to pensieve.thinkwrap.com [24.137.198.18] port 22. debug1: Connection established. debug1: identity file /home/thinkwrap/.ssh/identity type -1 debug1: identity file /home/thinkwrap/.ssh/identity-cert type -1 debug1: identity file /home/thinkwrap/.ssh/id_rsa type 1 debug1: identity file /home/thinkwrap/.ssh/id_rsa-cert type -1 debug1: identity file /home/thinkwrap/.ssh/id_dsa type -1 debug1: identity file /home/thinkwrap/.ssh/id_dsa-cert type -1 debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3 debug1: match: OpenSSH_5.3 pat OpenSSH* debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_5.3 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server-\u0026gt;client aes128-ctr hmac-md5 none debug1: kex: client-\u0026gt;server aes128-ctr hmac-md5 none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024\u0026lt;1024\u0026lt;8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Host \u0026#39;pensieve.thinkwrap.com\u0026#39; is known and matches the RSA host key. debug1: Found key in /home/thinkwrap/.ssh/known_hosts:2 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password debug1: Next authentication method: gssapi-keyex debug1: No valid Key exchange context debug1: Next authentication method: gssapi-with-mic debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file \u0026#39;/tmp/krb5cc_500\u0026#39; not found debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file \u0026#39;/tmp/krb5cc_500\u0026#39; not found debug1: Unspecified GSS failure. Minor code may provide more information debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file \u0026#39;/tmp/krb5cc_500\u0026#39; not found debug1: Next authentication method: publickey debug1: Offering public key: /home/thinkwrap/.ssh/id_rsa debug1: Remote: Forced command: /home/thinkwrap/gitolite/src/gitolite-shell miro.adamy+ATG11-TrainingVM debug1: Remote: Port forwarding disabled. debug1: Remote: X11 forwarding disabled. debug1: Remote: Agent forwarding disabled. debug1: Remote: Pty allocation disabled. debug1: Server accepts key: pkalg ssh-rsa blen 277 Agent admitted failure to sign using the key. debug1: Trying private key: /home/thinkwrap/.ssh/identity debug1: Trying private key: /home/thinkwrap/.ssh/id_dsa debug1: Next authentication method: password thinkwrap@pensieve.thinkwrap.com\u0026#39;s password: Solution # log-out, log on\nuse \u0026lsquo;ssh-add -D\u0026rsquo;\n","date":"May 22, 2015","externalUrl":null,"permalink":"/posts/2015-05-22-ssh-issue/","section":"Posts","summary":"After re-creating the SSH key, I got the above error from Gitolite.\nFull trace:\n➜ TWC ssh -v thinkwrap@pensieve.thinkwrap.com OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug1: Connecting to pensieve.thinkwrap.com [24.137.198.18] port 22. debug1: Connection established. debug1: identity file /home/thinkwrap/.ssh/identity type -1 debug1: identity file /home/thinkwrap/.ssh/identity-cert type -1 debug1: identity file /home/thinkwrap/.ssh/id_rsa type 1 debug1: identity file /home/thinkwrap/.ssh/id_rsa-cert type -1 debug1: identity file /home/thinkwrap/.ssh/id_dsa type -1 debug1: identity file /home/thinkwrap/.ssh/id_dsa-cert type -1 debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3 debug1: match: OpenSSH_5.3 pat OpenSSH* debug1: Enabling compatibility mode for protocol 2.0 debug1: Local version string SSH-2.0-OpenSSH_5.3 debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: server-\u003eclient aes128-ctr hmac-md5 none debug1: kex: client-\u003eserver aes128-ctr hmac-md5 none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024\u003c1024\u003c8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug1: Host 'pensieve.thinkwrap.com' is known and matches the RSA host key. debug1: Found key in /home/thinkwrap/.ssh/known_hosts:2 debug1: ssh_rsa_verify: signature correct debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password debug1: Next authentication method: gssapi-keyex debug1: No valid Key exchange context debug1: Next authentication method: gssapi-with-mic debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file '/tmp/krb5cc_500' not found debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file '/tmp/krb5cc_500' not found debug1: Unspecified GSS failure. Minor code may provide more information debug1: Unspecified GSS failure. Minor code may provide more information Credentials cache file '/tmp/krb5cc_500' not found debug1: Next authentication method: publickey debug1: Offering public key: /home/thinkwrap/.ssh/id_rsa debug1: Remote: Forced command: /home/thinkwrap/gitolite/src/gitolite-shell miro.adamy+ATG11-TrainingVM debug1: Remote: Port forwarding disabled. debug1: Remote: X11 forwarding disabled. debug1: Remote: Agent forwarding disabled. debug1: Remote: Pty allocation disabled. debug1: Server accepts key: pkalg ssh-rsa blen 277 Agent admitted failure to sign using the key. debug1: Trying private key: /home/thinkwrap/.ssh/identity debug1: Trying private key: /home/thinkwrap/.ssh/id_dsa debug1: Next authentication method: password thinkwrap@pensieve.thinkwrap.com's password: Solution # log-out, log on\n","title":"How to solve 'Agent admitted failure to sign using the key'","type":"post"},{"content":"Observed at QA environment. During automated shutdown sequence, the exception was thrown:\n$ bin/gdi-qa-com1.sh stop JBOSS_CMD_STOP = java -classpath /opt/jboss/jboss-as/bin/shutdown.jar:/opt/jboss/jboss-as/client/jnet.jar org.jboss.Shutdown --shutdown --user=admin --password=admin -s jnp://0.0.0.0:1099 Exception in thread \u0026#34;main\u0026#34; javax.naming.CommunicationException: Could not obtain connection to any of these urls: 0.0.0.0:1099 [Root exception is javax.naming.CommunicationException: Failed to connect to server /0.0.0.0:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused]]] at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1763) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:693) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686) at javax.naming.InitialContext.lookup(InitialContext.java:392) at org.jboss.Shutdown.main(Shutdown.java:219) Caused by: javax.naming.CommunicationException: Failed to connect to server /0.0.0.0:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused]] at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:335) at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1734) ... 4 more Caused by: javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused] at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:305) ... 5 more Caused by: java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:211) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) at java.net.Socket.connect(Socket.java:529) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:97) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:82) at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:301) ... 5 more To watch the log: tail -f /var/log/atg/gdi-qa-com1.log The conflict of 1099 between Endeca and ATG was resolved according Fixing port conflict on 1099 between out-of-the-box Endeca and JBOSS - the actual port was 11199\nThe environment variable for JBOSS instance were OK\n[jboss@gdi-app-l1 ~]$ env | grep JBOSS JBOSS_COM2_CONSOLE=/var/log/atg/gdi-qa-com2.log JBOSS_LDR_CONF=gdi-qa-ldr JBOSS_HOME=/opt/jboss/jboss-as JBOSS_COM2_HOST=0.0.0.0 JBOSS_STG_CONSOLE=/var/log/atg/gdi-qa-stg.log JBOSS_COM1_HOST=0.0.0.0 JBOSS_COM2_ADMINPORT=1199 JBOSS_COM1_CONSOLE=/var/log/atg/gdi-qa-com1.log JBOSS_STG_CONF=gdi-qa-stg JBOSS_STG_ADMINPORT=1299 JBOSS_STG_HOST=0.0.0.0 JBOSS_ADMINPASS=admin JBOSS_LDR_CONSOLE=/var/log/atg/gdi-qa-ldr.log JBOSS_USER=RUNASIS JBOSS_LDR_ADMINPORT=1399 JBOSS_LDR_HOST=0.0.0.0 JBOSS_COM1_ADMINPORT=1099 JBOSS_COM1_CONF=gdi-qa-com1 JBOSS_COM2_CONF=gdi-qa-com2 but these are used only for shutdown.\nThe actual port used for communication was:\n[jboss@gdi-app-l1 gdi-qa-com1]$ sudo netstat -tulpn | grep 27745 | grep 1099 tcp 0 0 0.0.0.0:11099 0.0.0.0:* LISTEN 27745/java [jboss@gdi-app-l1 gdi-qa-com1]$ sudo netstat -tulpn | grep 27745 | grep 109 tcp 0 0 0.0.0.0:11098 0.0.0.0:* LISTEN 27745/java tcp 0 0 0.0.0.0:11099 0.0.0.0:* LISTEN 27745/java This port is set in JBOSS file\n[jboss@gdi-app-l1 gdi-qa-com1]$ vim ./conf/bindingservice.beans/META-INF/bindings-jboss-beans.xml\nI have switched both 11098 and 11099 to 1098 and 1099.\nAfterwards, the shutdown works OK\n","date":"April 11, 2015","externalUrl":null,"permalink":"/posts/2015-04-11-jboss-shutdown/","section":"Posts","summary":"Observed at QA environment. During automated shutdown sequence, the exception was thrown:\n$ bin/gdi-qa-com1.sh stop JBOSS_CMD_STOP = java -classpath /opt/jboss/jboss-as/bin/shutdown.jar:/opt/jboss/jboss-as/client/jnet.jar org.jboss.Shutdown --shutdown --user=admin --password=admin -s jnp://0.0.0.0:1099 Exception in thread \"main\" javax.naming.CommunicationException: Could not obtain connection to any of these urls: 0.0.0.0:1099 [Root exception is javax.naming.CommunicationException: Failed to connect to server /0.0.0.0:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused]]] at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1763) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:693) at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:686) at javax.naming.InitialContext.lookup(InitialContext.java:392) at org.jboss.Shutdown.main(Shutdown.java:219) Caused by: javax.naming.CommunicationException: Failed to connect to server /0.0.0.0:1099 [Root exception is javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused]] at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:335) at org.jnp.interfaces.NamingContext.checkRef(NamingContext.java:1734) ... 4 more Caused by: javax.naming.ServiceUnavailableException: Failed to connect to server /0.0.0.0:1099 [Root exception is java.net.ConnectException: Connection refused] at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:305) ... 5 more Caused by: java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351) at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:211) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366) at java.net.Socket.connect(Socket.java:529) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:97) at org.jnp.interfaces.TimedSocketFactory.createSocket(TimedSocketFactory.java:82) at org.jnp.interfaces.NamingContext.getServer(NamingContext.java:301) ... 5 more To watch the log: tail -f /var/log/atg/gdi-qa-com1.log The conflict of 1099 between Endeca and ATG was resolved according Fixing port conflict on 1099 between out-of-the-box Endeca and JBOSS - the actual port was 11199\n","title":"Fixing the shutdown problem with JBoss","type":"post"},{"content":"","date":"April 11, 2015","externalUrl":null,"permalink":"/tags/jboss/","section":"Tags","summary":"","title":"Jboss","type":"tags"},{"content":" Git Inspector # Python based, requires Python 2.6+\nWorks OOTB on Mac\nInstallation # Download TAR from https://code.google.com/p/gitinspector/ unzipped to /opt/gitinspector-0.3.2: total 52K -rw-r--r-- 1 miro 999 Jul 29 2013 DESCRIPTION.txt -rw-r--r-- 1 miro 32K Jun 14 2013 LICENSE.txt -rw-r--r-- 1 miro 78 Jul 2 2013 MANIFEST.in -rw-r--r-- 1 miro 681 Jan 13 2014 README.txt drwxr-xr-x 45 miro 1.5K Mar 20 16:06 gitinspector -rw-r--r-- 1 miro 1.9K Jan 14 2014 setup.py -rw-r--r-- 1 miro 110 Jul 27 2013 stdeb.cfg create symlink to it from ~/bin (is on path) ln -s /opt/gitinspector-0.3.2/gitinspector/gitinspector.py ~/bin/gitinspector.py ➜ ~ ll ~/bin | grep gitin lrwxr-xr-x 1 miro 52 Mar 20 16:06 gitinspector.py -\u0026gt; /opt/gitinspector-0.3.2/gitinspector/gitinspector.py Example # ➜ gitinspector git:(master) ~/bin/gitinspector.py -Tlr --since=2014-01-01 --until=2015-05-05 Statistical information for the repository \u0026#39;gitinspector\u0026#39; was gathered on 2019/11/27. The following historical commit information, by author, was found in the repository: Author Commits Insertions Deletions % of changes Adam Waldenberg 41 569 249 95.34 Chris Barry 1 3 3 0.70 Christian Kastner 2 9 5 1.63 Diomidis Spinellis 2 3 3 0.70 Dmitry Dzhus 1 3 3 0.70 Jon Warghed 1 1 0 0.12 Yannick Moy 1 4 3 0.82 Below are the number of rows from each author that have survived and are still intact in the current revision: Author Rows Stability Age % in comments Adam Waldenberg 468 82.2 8.7 6.84 Chris Barry 3 100.0 4.5 0.00 Christian Kastner 8 88.9 3.3 0.00 Diomidis Spinellis 1 33.3 4.0 100.00 Dmitry Dzhus 3 100.0 2.6 0.00 Jon Warghed 1 100.0 3.2 0.00 Yannick Moy 3 75.0 3.7 0.00 The following history timeline has been gathered from the repository: Author 2014-01 2014-02 2014-03 2014-11 2014-12 2015-02 Adam Waldenberg -+++++++ --++++++ ---+++++ ----+++++ --+++++++ -+++++++ Chris Barry . Christian Kastner . Diomidis Spinellis . Dmitry Dzhus . Jon Warghed . Yannick Moy . Modified Rows: 170 387 7 223 64 7 The following responsibilities, by author, were found in the current revision of the repository (comments are excluded from the line count, if possible): Adam Waldenberg is mostly responsible for: 128 gitinspector/metrics.py 97 gitinspector/blame.py 30 gitinspector/localization.py 29 gitinspector/clone.py 26 gitinspector/terminal.py 26 gitinspector/basedir.py 19 gitinspector/changes.py 17 gitinspector/filtering.py 16 gitinspector/format.py 15 gitinspector/gitinspector.py Chris Barry is mostly responsible for: 2 gitinspector/format.py 1 gitinspector/gravatar.py Christian Kastner is mostly responsible for: 5 gitinspector/basedir.py 3 gitinspector/format.py Dmitry Dzhus is mostly responsible for: 3 gitinspector/comment.py Jon Warghed is mostly responsible for: 1 gitinspector/changes.py Yannick Moy is mostly responsible for: 3 gitinspector/comment.py The extensions below were found in the repository history (extensions used during statistical analysis are marked): 1 css header html po pot [py] txt ","date":"March 20, 2015","externalUrl":null,"permalink":"/posts/2015-03-20-git-project-stat/","section":"Posts","summary":"Git Inspector # Python based, requires Python 2.6+\nWorks OOTB on Mac\nInstallation # Download TAR from https://code.google.com/p/gitinspector/ unzipped to /opt/gitinspector-0.3.2: total 52K -rw-r--r-- 1 miro 999 Jul 29 2013 DESCRIPTION.txt -rw-r--r-- 1 miro 32K Jun 14 2013 LICENSE.txt -rw-r--r-- 1 miro 78 Jul 2 2013 MANIFEST.in -rw-r--r-- 1 miro 681 Jan 13 2014 README.txt drwxr-xr-x 45 miro 1.5K Mar 20 16:06 gitinspector -rw-r--r-- 1 miro 1.9K Jan 14 2014 setup.py -rw-r--r-- 1 miro 110 Jul 27 2013 stdeb.cfg create symlink to it from ~/bin (is on path) ln -s /opt/gitinspector-0.3.2/gitinspector/gitinspector.py ~/bin/gitinspector.py ➜ ~ ll ~/bin | grep gitin lrwxr-xr-x 1 miro 52 Mar 20 16:06 gitinspector.py -\u003e /opt/gitinspector-0.3.2/gitinspector/gitinspector.py Example # ➜ gitinspector git:(master) ~/bin/gitinspector.py -Tlr --since=2014-01-01 --until=2015-05-05 Statistical information for the repository 'gitinspector' was gathered on 2019/11/27. The following historical commit information, by author, was found in the repository: Author Commits Insertions Deletions % of changes Adam Waldenberg 41 569 249 95.34 Chris Barry 1 3 3 0.70 Christian Kastner 2 9 5 1.63 Diomidis Spinellis 2 3 3 0.70 Dmitry Dzhus 1 3 3 0.70 Jon Warghed 1 1 0 0.12 Yannick Moy 1 4 3 0.82 Below are the number of rows from each author that have survived and are still intact in the current revision: Author Rows Stability Age % in comments Adam Waldenberg 468 82.2 8.7 6.84 Chris Barry 3 100.0 4.5 0.00 Christian Kastner 8 88.9 3.3 0.00 Diomidis Spinellis 1 33.3 4.0 100.00 Dmitry Dzhus 3 100.0 2.6 0.00 Jon Warghed 1 100.0 3.2 0.00 Yannick Moy 3 75.0 3.7 0.00 The following history timeline has been gathered from the repository: Author 2014-01 2014-02 2014-03 2014-11 2014-12 2015-02 Adam Waldenberg -+++++++ --++++++ ---+++++ ----+++++ --+++++++ -+++++++ Chris Barry . Christian Kastner . Diomidis Spinellis . Dmitry Dzhus . Jon Warghed . Yannick Moy . Modified Rows: 170 387 7 223 64 7 The following responsibilities, by author, were found in the current revision of the repository (comments are excluded from the line count, if possible): Adam Waldenberg is mostly responsible for: 128 gitinspector/metrics.py 97 gitinspector/blame.py 30 gitinspector/localization.py 29 gitinspector/clone.py 26 gitinspector/terminal.py 26 gitinspector/basedir.py 19 gitinspector/changes.py 17 gitinspector/filtering.py 16 gitinspector/format.py 15 gitinspector/gitinspector.py Chris Barry is mostly responsible for: 2 gitinspector/format.py 1 gitinspector/gravatar.py Christian Kastner is mostly responsible for: 5 gitinspector/basedir.py 3 gitinspector/format.py Dmitry Dzhus is mostly responsible for: 3 gitinspector/comment.py Jon Warghed is mostly responsible for: 1 gitinspector/changes.py Yannick Moy is mostly responsible for: 3 gitinspector/comment.py The extensions below were found in the repository history (extensions used during statistical analysis are marked): 1 css header html po pot [py] txt","title":"Git project statistic tool","type":"post"},{"content":"When git uses less as pager the output of commands like git log disappears from the console screen when you exit from less. This is not convenient in many cases so here is how to fix this.\nJust for git commands:\ngit config --global --replace-all core.pager \u0026#34;less -iXFR\u0026#34; For less globally (including git) - add to .bashrc / .zshrc / etc:\nexport LESS=-iXFR The options we set for less are:\n* -i - ignore case when searching (but respect case if search term contains uppercase letters) * -X - do not clear screen on exit * -F - exit if text is less then one screen long * -R - was on by default on my system, something related to colors Source: http://serebrov.github.io/html/2014-01-04-git-log-and-less-keep-output.html\n","date":"March 10, 2015","externalUrl":null,"permalink":"/posts/2015-03-10-git-log-output-less/","section":"Posts","summary":"When git uses less as pager the output of commands like git log disappears from the console screen when you exit from less. This is not convenient in many cases so here is how to fix this.\nJust for git commands:\ngit config --global --replace-all core.pager \"less -iXFR\" For less globally (including git) - add to .bashrc / .zshrc / etc:\nexport LESS=-iXFR The options we set for less are:\n","title":"How to keep git log and less output on the screen","type":"post"},{"content":" That is what I do - jump from project to project to topic to project. And back.\nIt is uncertain how good is all this - but as they say:\n\u0026ldquo;If you cannot do something right, learn to enjoy doing it poorly\u0026rdquo;\n","date":"February 16, 2015","externalUrl":null,"permalink":"/posts/2015-02-16-grasshoper/","section":"Posts","summary":" That is what I do - jump from project to project to topic to project. And back.\nIt is uncertain how good is all this - but as they say:\n“If you cannot do something right, learn to enjoy doing it poorly”\n","title":"New image that expresses my new undefined job title","type":"post"},{"content":"","date":"February 16, 2015","externalUrl":null,"permalink":"/categories/startuplife/","section":"Categories","summary":"","title":"Startuplife","type":"categories"},{"content":"This one goes beyond git, but is very useful. Ruby script that produces this:\nHere is the script\n#!/usr/bin/env ruby require \u0026#39;rubygems\u0026#39; gem \u0026#39;term-ansicolor\u0026#39;, \u0026#39;=1.3.0\u0026#39; require \u0026#39;term/ansicolor\u0026#39; class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:\u0026#34;%h %ad %an - %s\u0026#34; #{sha}~1..#{sha}` end def unmerged? content =~ /^\\+/ end def equivalent? content =~ /^\\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches \u0026lt; Array def self.clean_branch_output(str) str.split(/\\n/).map{ |e| e.strip.gsub(/\\*\\s+/, \u0026#39;\u0026#39;) }.reject{ |branch| branch =~ /\\b#{Regexp.escape(UPSTREAM)}\\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\\n/).map{ |c| GitCommit.new(c) } git_branches \u0026lt;\u0026lt; GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = \u0026#34;1.0.1\u0026#34; include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local =\u0026gt; local?, :remote =\u0026gt; remote?) end def print_overview load if branches.any_missing_commits? puts \u0026#34;The following branches possibly have commits not merged to #{upstream}:\u0026#34; branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts \u0026lt;\u0026lt;-EOT.gsub(/^\\s+\\|/, \u0026#39;\u0026#39;) |Usage: #{$0} [-a] [--upstream \u0026lt;branch\u0026gt;] [--remote] | |This script wraps the \u0026#34;git cherry\u0026#34; command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow(\u0026#34;yellow\u0026#34;)} commits have not been merged | #{green(\u0026#34;green\u0026#34;)} commits have equivalent changes in \u0026lt;upstream\u0026gt; but different SHAs | |The default upstream is \u0026#39;master\u0026#39;. | |OPTIONS: | -a display all unmerged commits (verbose) | --remote compare remote branches instead of local branches | --upstream \u0026lt;branch\u0026gt; specify a specific upstream branch | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type \u0026#34;git unmerged\u0026#34; to use it. If you\u0026#39;d like to name | it something else and still refer to it with \u0026#34;git unmerged\u0026#34; then you\u0026#39;ll | need to set up an alias: | git config --global alias.unmerged \\\\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis \u0026lt;zdennis@mutuallyhuman.com\u0026gt; EOT exit end def print_version puts \u0026#34;#{VERSION}\u0026#34; end def branch_description local? ? \u0026#34;local\u0026#34; : \u0026#34;remote\u0026#34; end def print_specifics load if branches.any_missing_commits? print_breakdown else puts \u0026#34;There are no #{branch_description} branches out of sync with #{upstream}\u0026#34; end end def print_breakdown puts \u0026#34;Below is a breakdown for each branch. Here\u0026#39;s a legend:\u0026#34; puts print_legend branches.each do |branch| puts print \u0026#34;#{branch.name}:\u0026#34; if branch.unmerged_commits.empty? \u0026amp;\u0026amp; !show_equivalent_commits? print \u0026#34;(no umerged commits, must have merged commits with different SHAs)\\n\u0026#34; else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts \u0026#34; \u0026#34; + yellow(\u0026#34;yellow\u0026#34;) + \u0026#34; commits have not been merged\u0026#34; puts \u0026#34; \u0026#34; + green(\u0026#34;green\u0026#34;) + \u0026#34; commits have equivalent changes in #{UPSTREAM} but different SHAs\u0026#34; if show_equivalent_commits? end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? \u0026#34;master\u0026#34; elsif remote? \u0026#34;origin/master\u0026#34; end end private def extract_options_from_args(args) if args.include?(\u0026#34;--remote\u0026#34;) @options[:remote] = true else @options[:local] = true end @options[:show_help] = true if args.include?(\u0026#34;-h\u0026#34;) || args.include?(\u0026#34;--help\u0026#34;) @options[:show_equivalent_commits] = true if args.include?(\u0026#34;-a\u0026#34;) @options[:show_version] = true if args.include?(\u0026#34;-v\u0026#34;) || args.include?(\u0026#34;--version\u0026#34;) if index=args.index(\u0026#34;--upstream\u0026#34;) @options[:upstream] = args[index+1] end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics end ","date":"February 5, 2015","externalUrl":null,"permalink":"/posts/2015-02-05-unmerged/","section":"Posts","summary":"This one goes beyond git, but is very useful. Ruby script that produces this:\nHere is the script\n#!/usr/bin/env ruby require 'rubygems' gem 'term-ansicolor', '=1.3.0' require 'term/ansicolor' class GitCommit attr_reader :content def initialize(content) @content = content end def sha @content.split[1] end def to_s `git log --pretty=format:\"%h %ad %an - %s\" #{sha}~1..#{sha}` end def unmerged? content =~ /^\\+/ end def equivalent? content =~ /^\\-/ end end class GitBranch attr_reader :name, :commits def initialize(name, commits) @name = name @commits = commits end def unmerged_commits commits.select{ |commit| commit.unmerged? } end def equivalent_commits commits.select{ |commit| commit.equivalent? } end end class GitBranches \u003c Array def self.clean_branch_output(str) str.split(/\\n/).map{ |e| e.strip.gsub(/\\*\\s+/, '') }.reject{ |branch| branch =~ /\\b#{Regexp.escape(UPSTREAM)}\\b/ }.sort end def self.local_branches clean_branch_output `git branch` end def self.remote_branches clean_branch_output `git branch -r` end def self.load(options) git_branches = new branches = if options[:local] local_branches elsif options[:remote] remote_branches end branches.each do |branch| raw_commits = `git cherry -v #{UPSTREAM} #{branch}`.split(/\\n/).map{ |c| GitCommit.new(c) } git_branches \u003c\u003c GitBranch.new(branch, raw_commits) end git_branches end def unmerged reject{ |branch| branch.commits.empty? }.sort_by{ |branch| branch.name } end def any_missing_commits? select{ |branch| branch.commits.any? }.any? end end class GitUnmerged VERSION = \"1.0.1\" include Term::ANSIColor attr_reader :branches def initialize(args) @options = {} extract_options_from_args(args) end def load @branches ||= GitBranches.load(:local =\u003e local?, :remote =\u003e remote?) end def print_overview load if branches.any_missing_commits? puts \"The following branches possibly have commits not merged to #{upstream}:\" branches.each do |branch| num_unmerged = yellow(branch.unmerged_commits.size.to_s) num_equivalent = green(branch.equivalent_commits.size.to_s) puts %| #{branch.name} (#{num_unmerged}/#{num_equivalent} commits)| end end end def print_help puts \u003c\u003c-EOT.gsub(/^\\s+\\|/, '') |Usage: #{$0} [-a] [--upstream \u003cbranch\u003e] [--remote] | |This script wraps the \"git cherry\" command. It reports the commits from all local |branches which have not been merged into an upstream branch. | | #{yellow(\"yellow\")} commits have not been merged | #{green(\"green\")} commits have equivalent changes in \u003cupstream\u003e but different SHAs | |The default upstream is 'master'. | |OPTIONS: | -a display all unmerged commits (verbose) | --remote compare remote branches instead of local branches | --upstream \u003cbranch\u003e specify a specific upstream branch | |EXAMPLE: check for all unmerged commits | #{$0} | |EXAMPLE: check for all unmerged commits and merged commits (but with a different SHA) | #{$0} -a | |EXAMPLE: use a different upstream than master | #{$0} --upstream otherbranch | |EXAMPLE: compare remote branches against origin/master | #{$0} --remote | |GITCONFIG: | If you name this file git-unmerged and place it somewhere in your PATH | you will be able to type \"git unmerged\" to use it. If you'd like to name | it something else and still refer to it with \"git unmerged\" then you'll | need to set up an alias: | git config --global alias.unmerged \\\\!#{$0} | |Version: #{VERSION} |Author: Zach Dennis \u003czdennis@mutuallyhuman.com\u003e EOT exit end def print_version puts \"#{VERSION}\" end def branch_description local? ? \"local\" : \"remote\" end def print_specifics load if branches.any_missing_commits? print_breakdown else puts \"There are no #{branch_description} branches out of sync with #{upstream}\" end end def print_breakdown puts \"Below is a breakdown for each branch. Here's a legend:\" puts print_legend branches.each do |branch| puts print \"#{branch.name}:\" if branch.unmerged_commits.empty? \u0026\u0026 !show_equivalent_commits? print \"(no umerged commits, must have merged commits with different SHAs)\\n\" else puts end branch.unmerged_commits.each { |commit| puts yellow(commit.to_s) } if show_equivalent_commits? branch.equivalent_commits.each do |commit| puts green(commit.to_s) end end end end def print_legend load puts \" \" + yellow(\"yellow\") + \" commits have not been merged\" puts \" \" + green(\"green\") + \" commits have equivalent changes in #{UPSTREAM} but different SHAs\" if show_equivalent_commits? end def show_help? ; @options[:show_help] ; end def show_equivalent_commits? ; @options[:show_equivalent_commits] ; end def show_version? ; @options[:show_version] ; end def upstream if @options[:upstream] @options[:upstream] elsif local? \"master\" elsif remote? \"origin/master\" end end private def extract_options_from_args(args) if args.include?(\"--remote\") @options[:remote] = true else @options[:local] = true end @options[:show_help] = true if args.include?(\"-h\") || args.include?(\"--help\") @options[:show_equivalent_commits] = true if args.include?(\"-a\") @options[:show_version] = true if args.include?(\"-v\") || args.include?(\"--version\") if index=args.index(\"--upstream\") @options[:upstream] = args[index+1] end end def local? ; @options[:local] ; end def remote? ; @options[:remote] ; end end unmerged = GitUnmerged.new ARGV UPSTREAM = unmerged.upstream if unmerged.show_help? unmerged.print_help exit elsif unmerged.show_version? unmerged.print_version exit else unmerged.print_overview puts unmerged.print_specifics end","title":"Finding unmerged commits in all branches","type":"post"},{"content":"The groovy script does parse the XML files (scraped from dyn-admin, or output of the XML combine) and produces file in the syntax of Plant UML - http://plantuml.sourceforge.net\nif (args.size() == 0) { println \u0026#34;Usage: groovy extractItems.groovy XMLFILE-IN-GSA-FORMAT.xml\u0026#34; System.exit(1) } def gsaFile = new XmlSlurper().parseText(new File(args[0]).text) def desc = gsaFile.\u0026#39;item-descriptor\u0026#39; def processItemDescriptor(myDesc) { def info = [:] def tables = [] def props = [:] def descriptors = [:] for (table in myDesc.table) { String tableName = table.@name.text() tables += tableName // collect table\u0026#39;s properties for (prop in table.property) { String name = \u0026#34;${prop.@name.text()}(${tableName})\u0026#34;.replaceAll(/[ -]/, \u0026#39;_\u0026#39;) props[name] = [:] if (\u0026#34;${prop.@\u0026#39;required\u0026#39;.text()}\u0026#34; != \u0026#34;\u0026#34;) { props[name][\u0026#39;required\u0026#39;] = \u0026#34;${prop.@\u0026#39;required\u0026#39;.text()}\u0026#34; } if (\u0026#34;${prop.@\u0026#39;hidden\u0026#39;.text()}\u0026#34; != \u0026#34;\u0026#34;) { props[name][\u0026#39;hidden\u0026#39;] = \u0026#34;${prop.@\u0026#39;hidden\u0026#39;.text()}\u0026#34; } if (\u0026#34;${prop.@\u0026#39;item-type\u0026#39;.text()}\u0026#34; != \u0026#34;\u0026#34;) { props[name][\u0026#39;item-type\u0026#39;] = \u0026#34;${prop.@\u0026#39;item-type\u0026#39;.text()}\u0026#34; descriptors[\u0026#34;${prop.@name.text()}\u0026#34;] = \u0026#34;${prop.@\u0026#39;item-type\u0026#39;.text().replaceAll(/[ -]/, \u0026#39;_\u0026#39;)}\u0026#34; } } } info[\u0026#39;tables\u0026#39;] = tables // scan for properties outside of tables for (prop in myDesc.property) { String name = \u0026#34;${prop.@name.text()}\u0026#34;.replaceAll(/[ -]/, \u0026#39;_\u0026#39;) props[name] = [:] if (\u0026#34;${prop.@\u0026#39;item-type\u0026#39;.text()}\u0026#34; != \u0026#34;\u0026#34;) { props[name][\u0026#39;item-type\u0026#39;] = \u0026#34;${prop.@\u0026#39;item-type\u0026#39;.text()}\u0026#34; } } info[\u0026#39;properties\u0026#39;] = props info[\u0026#39;descriptors\u0026#39;] = descriptors return info } println \u0026#34;Got ${desc.size()} item-descriptors\u0026#34; println \u0026#34;@startuml\u0026#34; for (idesc in desc) { def info = processItemDescriptor(idesc) def name = \u0026#34;${idesc.@name.text().replaceAll(/[ -]/, \u0026#39;_\u0026#39;)}\u0026#34; println \u0026#34;\\nclass ${name} {\u0026#34; for (p in info.tables) println \u0026#34;\\t\u0026#34;+p println \u0026#34;..\u0026#34; for (p in info.properties) println \u0026#34;\\t\u0026#34;+p println \u0026#34;}\u0026#34; for (p in info.descriptors?.keySet()) println \u0026#34;\\t ${name} *-- ${info.descriptors[p]} : ${p}\u0026#34; } println \u0026#34;@enduml\u0026#34; The generation (requires installed dot tools)\ngroovy ./extractItems.groovy pricing-generated.xml \u0026gt;pricing.uml groovy ./extractItems.groovy catalog-generated.xml \u0026gt;catalog.uml java -jar /opt/diagram/plantuml.jar catalog.uml java -jar /opt/diagram/plantuml.jar pricing.uml The files I used:\ncatalog-generated.xml Output - catalog.uml Here is the generated image:\nWhat is included # Every item descriptor contains\nlist of database tables used list of properties. If property is from table, it has its name as parameter links between descriptors are rendered and annotated by the property that holds it See also GitHub - https://github.com/miroadamy/atg-repository-visualizer\n","date":"November 4, 2014","externalUrl":null,"permalink":"/posts/2014-11-04-atg-repo-visualizer/","section":"Posts","summary":"The groovy script does parse the XML files (scraped from dyn-admin, or output of the XML combine) and produces file in the syntax of Plant UML - http://plantuml.sourceforge.net\nif (args.size() == 0) { println \"Usage: groovy extractItems.groovy XMLFILE-IN-GSA-FORMAT.xml\" System.exit(1) } def gsaFile = new XmlSlurper().parseText(new File(args[0]).text) def desc = gsaFile.'item-descriptor' def processItemDescriptor(myDesc) { def info = [:] def tables = [] def props = [:] def descriptors = [:] for (table in myDesc.table) { String tableName = table.@name.text() tables += tableName // collect table's properties for (prop in table.property) { String name = \"${prop.@name.text()}(${tableName})\".replaceAll(/[ -]/, '_') props[name] = [:] if (\"${prop.@'required'.text()}\" != \"\") { props[name]['required'] = \"${prop.@'required'.text()}\" } if (\"${prop.@'hidden'.text()}\" != \"\") { props[name]['hidden'] = \"${prop.@'hidden'.text()}\" } if (\"${prop.@'item-type'.text()}\" != \"\") { props[name]['item-type'] = \"${prop.@'item-type'.text()}\" descriptors[\"${prop.@name.text()}\"] = \"${prop.@'item-type'.text().replaceAll(/[ -]/, '_')}\" } } } info['tables'] = tables // scan for properties outside of tables for (prop in myDesc.property) { String name = \"${prop.@name.text()}\".replaceAll(/[ -]/, '_') props[name] = [:] if (\"${prop.@'item-type'.text()}\" != \"\") { props[name]['item-type'] = \"${prop.@'item-type'.text()}\" } } info['properties'] = props info['descriptors'] = descriptors return info } println \"Got ${desc.size()} item-descriptors\" println \"@startuml\" for (idesc in desc) { def info = processItemDescriptor(idesc) def name = \"${idesc.@name.text().replaceAll(/[ -]/, '_')}\" println \"\\nclass ${name} {\" for (p in info.tables) println \"\\t\"+p println \"..\" for (p in info.properties) println \"\\t\"+p println \"}\" for (p in info.descriptors?.keySet()) println \"\\t ${name} *-- ${info.descriptors[p]} : ${p}\" } println \"@enduml\" The generation (requires installed dot tools)\n","title":"ATG Repository structure visualizer","type":"post"},{"content":" If annoyed with: # ➜ ~ echo $PATH | tr \u0026#39;:\u0026#39; \u0026#39;\\n\u0026#39; /usr/local/opt/coreutils/libexec/gnubin /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin /opt/ant/bin /opt/groovy/bin /opt/gradle/bin /Users/miro/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/texbin # YEs I am using GNU core utils but grep is not there # The issue ➜ ~ grep --version grep (BSD grep) 2.5.1-FreeBSD Here is the receipt\nhttp://www.heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html\nDid not install it as the issue was not with grep:\nInstead, use findInJars.sh\n➜ ~ cat ~/bin/findInJars.sh #!/bin/bash pattern=$1 shift for jar in $(find $* -type f -name \u0026#34;*.jar\u0026#34;) do # echo Checking: $jar match=`jar -tvf $jar | grep $pattern` if [ ! -z \u0026#34;$match\u0026#34; ] then echo \u0026#34;Found in: $jar\u0026#34; echo \u0026#34;$match\u0026#34; fi done ➜ ~ ~/bin/findInJars.sh atg.taglib.dspjsp.IncludeTag ~/ATG Found in: /Users/miro/ATG/ACC11.0/10.1.2/DAS/lib/classes.jar 1924 Thu Dec 13 05:02:52 EST 2012 atg/taglib/dspjsp/IncludeTag$DspIncludeResponseWrapper.class 1081 Thu Dec 13 05:02:52 EST 2012 atg/taglib/dspjsp/IncludeTag$ReverseLayerMapInfo.class 22844 Thu Dec 13 05:02:52 EST 2012 atg/taglib/dspjsp/IncludeTag.class Found in: /Users/miro/ATG/ACC11.0/11.0/DAS/lib/classes.jar 2537 Thu Dec 05 10:54:12 EST 2013 atg/taglib/dspjsp/IncludeTag$DspIncludeResponseWrapper.class 1081 Thu Dec 05 10:54:12 EST 2013 atg/taglib/dspjsp/IncludeTag$ReverseLayerMapInfo.class 24003 Thu Dec 05 10:54:12 EST 2013 atg/taglib/dspjsp/IncludeTag.class ","date":"November 2, 2014","externalUrl":null,"permalink":"/posts/2014-11-02-bsd-grep-gnu/","section":"Posts","summary":"If annoyed with: # ➜ ~ echo $PATH | tr ':' '\\n' /usr/local/opt/coreutils/libexec/gnubin /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin /opt/ant/bin /opt/groovy/bin /opt/gradle/bin /Users/miro/bin /usr/local/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/texbin # YEs I am using GNU core utils but grep is not there # The issue ➜ ~ grep --version grep (BSD grep) 2.5.1-FreeBSD Here is the receipt\n","title":"Replace BSD grep with GNU grep","type":"post"},{"content":"When trying to start DBeaver (http://dbeaver.jkiss.org) I got this\nI do have Java 7 installed:\n➜ Contents java -version java version \u0026#34;1.7.0_55\u0026#34; Java(TM) SE Runtime Environment (build 1.7.0_55-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode) ➜ Contents which java java is /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin/java java is /usr/bin/java which should be a superset. But it is not.\nSolution # Oracle seems to screw up the PLIST capabilities in JAva7 install\nGo to\n➜ ~ cd /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents ➜ Contents ll total 8 drwxrwxr-x 15 root wheel 510B 17 Mar 2014 Home -rw-rw-r-- 1 root wheel 1.5K 17 Mar 2014 Info.plist drwxrwxr-x 3 root wheel 102B 21 Apr 12:07 MacOScode And edit the Info.plist, adding following values to JVMCapabilities key (originally has just \u0026lt;string\u0026gt;CommandLine\u0026lt;/string\u0026gt;)\nAfterwards, I had to restart the Pathfinder (or whatever shell you use).\nBEFORE # \u0026lt;key\u0026gt;JVMCapabilities\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;CommandLine\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; AFTER # \u0026lt;key\u0026gt;JVMCapabilities\u0026lt;/key\u0026gt; \u0026lt;array\u0026gt; \u0026lt;string\u0026gt;JNI\u0026lt;/string\u0026gt; \u0026lt;string\u0026gt;BundledApp\u0026lt;/string\u0026gt; \u0026lt;string\u0026gt;WebStart\u0026lt;/string\u0026gt; \u0026lt;string\u0026gt;Applets\u0026lt;/string\u0026gt; \u0026lt;string\u0026gt;CommandLine\u0026lt;/string\u0026gt; \u0026lt;/array\u0026gt; Source http://crunchify.com/os-x-mavericks-eclipse-java-issue/\n","date":"October 14, 2014","externalUrl":null,"permalink":"/posts/2014-10-14-java6required/","section":"Posts","summary":"When trying to start DBeaver (http://dbeaver.jkiss.org) I got this\nI do have Java 7 installed:\n➜ Contents java -version java version \"1.7.0_55\" Java(TM) SE Runtime Environment (build 1.7.0_55-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.55-b03, mixed mode) ➜ Contents which java java is /Library/Java/JavaVirtualMachines/jdk1.7.0_55.jdk/Contents/Home/bin/java java is /usr/bin/java which should be a superset. But it is not.\nSolution # Oracle seems to screw up the PLIST capabilities in JAva7 install\n","title":"Dealing with 'Java Runtime SE 6' required error","type":"post"},{"content":"See https://github.com/gesellix/keepass-node\n➜ keepass-node git:(master) pwd /Users/miro/src/PLG/keepass-node Install # ➜ keepass-node git:(master) ✗ sudo npm install Password: \u0026gt; dejavu@0.4.4 postinstall /Users/miro/src/PLG/keepass-node/node_modules/keepass.io/node_modules/dejavu \u0026gt; node bin/post_install.js Saving runtime configuration in /Users/miro/src/PLG/keepass-node/node_modules/keepass.io/.dejavurc \u0026gt; keepass.io@1.0.5 install /Users/miro/src/PLG/keepass-node/node_modules/keepass.io \u0026gt; (node-gyp rebuild 2\u0026gt;\u0026amp;1) || (echo \u0026#39;DO NOT WORRY ABOUT THESE MESSAGES. KEEPASS.IO WILL FALLBACK TO SLOWER NODE.JS METHODS, SO THERE ARE NO LIMITATIONS EXCEPT SLOWER PERFORMANCE.\u0026#39;; exit 0) \\ Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 69 gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23) gyp ERR! stack at ChildProcess.emit (events.js:98:17) gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:810:12) gyp ERR! System Darwin 13.4.0 gyp ERR! command \u0026#34;node\u0026#34; \u0026#34;/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js\u0026#34; \u0026#34;rebuild\u0026#34; gyp ERR! cwd /Users/miro/src/PLG/keepass-node/node_modules/keepass.io gyp ERR! node -v v0.10.31 gyp ERR! node-gyp -v v1.0.1 gyp ERR! not ok DO NOT WORRY ABOUT THESE MESSAGES. KEEPASS.IO WILL FALLBACK TO SLOWER NODE.JS METHODS, SO THERE ARE NO LIMITATIONS EXCEPT SLOWER PERFORMANCE. chai-as-promised@4.1.1 node_modules/chai-as-promised underscore@1.7.0 node_modules/underscore q@1.0.1 node_modules/q compression@1.1.0 node_modules/compression ├── bytes@1.0.0 ├── on-headers@1.0.0 ├── vary@1.0.0 ├── debug@2.0.0 (ms@0.6.2) ├── compressible@2.0.0 (mime-db@1.0.3) └── accepts@1.1.1 (negotiator@0.4.8, mime-types@2.0.2) chai@1.9.2 node_modules/chai ├── assertion-error@1.0.0 └── deep-eql@0.1.3 (type-detect@0.1.1) express@4.9.5 node_modules/express ├── merge-descriptors@0.0.2 ├── utils-merge@1.0.0 ├── fresh@0.2.4 ├── cookie@0.1.2 ├── escape-html@1.0.1 ├── range-parser@1.0.2 ├── cookie-signature@1.0.5 ├── media-typer@0.3.0 ├── vary@1.0.0 ├── finalhandler@0.2.0 ├── parseurl@1.3.0 ├── methods@1.1.0 ├── serve-static@1.6.3 ├── path-to-regexp@0.1.3 ├── depd@0.4.5 ├── qs@2.2.4 ├── debug@2.0.0 (ms@0.6.2) ├── on-finished@2.1.0 (ee-first@1.0.5) ├── etag@1.4.0 (crc@3.0.0) ├── proxy-addr@1.0.3 (forwarded@0.1.0, ipaddr.js@0.1.3) ├── send@0.9.3 (destroy@1.0.3, ms@0.6.2, mime@1.2.11) ├── type-is@1.5.2 (mime-types@2.0.2) └── accepts@1.1.1 (negotiator@0.4.8, mime-types@2.0.2) mocha@1.21.4 node_modules/mocha ├── diff@1.0.7 ├── growl@1.8.1 ├── commander@2.0.0 ├── mkdirp@0.3.5 ├── debug@2.0.0 (ms@0.6.2) ├── jade@0.26.3 (commander@0.6.1, mkdirp@0.3.0) └── glob@3.2.3 (inherits@2.0.1, graceful-fs@2.0.3, minimatch@0.2.14) body-parser@1.9.0 node_modules/body-parser ├── bytes@1.0.0 ├── media-typer@0.3.0 ├── raw-body@1.3.0 ├── depd@1.0.0 ├── qs@2.2.4 ├── iconv-lite@0.4.4 ├── on-finished@2.1.0 (ee-first@1.0.5) └── type-is@1.5.2 (mime-types@2.0.2) coveralls@2.11.2 node_modules/coveralls ├── lcov-parse@0.0.6 ├── log-driver@1.2.4 ├── request@2.40.0 (json-stringify-safe@5.0.0, forever-agent@0.5.2, aws-sign2@0.5.0, oauth-sign@0.3.0, stringstream@0.0.4, tunnel-agent@0.4.0, qs@1.0.2, node-uuid@1.4.1, mime-types@1.0.2, tough-cookie@0.12.1, form-data@0.1.4, http-signature@0.10.0, hawk@1.1.1) └── js-yaml@3.0.1 (esprima@1.0.4, argparse@0.1.15) istanbul@0.3.2 node_modules/istanbul ├── abbrev@1.0.5 ├── which@1.0.5 ├── nopt@3.0.1 ├── wordwrap@0.0.2 ├── once@1.3.1 (wrappy@1.0.1) ├── async@0.9.0 ├── resolve@0.7.4 ├── mkdirp@0.5.0 (minimist@0.0.8) ├── fileset@0.1.5 (minimatch@0.4.0, glob@3.2.11) ├── esprima@1.2.2 ├── escodegen@1.3.3 (estraverse@1.5.1, esutils@1.0.0, source-map@0.1.40, esprima@1.1.1) ├── handlebars@1.3.0 (optimist@0.3.7, uglify-js@2.3.6) └── js-yaml@3.2.2 (esprima@1.0.4, argparse@0.1.15) googleapis@1.0.14 node_modules/googleapis ├── async@0.9.0 ├── multipart-stream@1.0.0 (inherits@2.0.1, sandwich-stream@0.0.4) ├── request@2.40.0 (json-stringify-safe@5.0.0, aws-sign2@0.5.0, forever-agent@0.5.2, oauth-sign@0.3.0, stringstream@0.0.4, tunnel-agent@0.4.0, qs@1.0.2, node-uuid@1.4.1, mime-types@1.0.2, form-data@0.1.4, tough-cookie@0.12.1, http-signature@0.10.0, hawk@1.1.1) └── gapitoken@0.1.3 (jws@0.0.2) keepass.io@1.0.5 node_modules/keepass.io ├── async@0.9.0 ├── nan@1.2.0 ├── xml2js@0.4.4 (sax@0.6.0, xmlbuilder@2.4.4) └── dejavu@0.4.4 (amdefine@0.0.8, mout@0.4.0) ➜ keepass-node git:(master) Kinda weird to ignore errors, but anyway \u0026hellip;\nStart # ➜ keepass-node git:(master) npm start \u0026gt; keepass-node@0.0.1 start /Users/miro/src/PLG/keepass-node \u0026gt; node ./server.js server is listening on port 8443 All kbdx files must be in /local/ directory.\nAlso supports loading from Google Drive\n","date":"October 3, 2014","externalUrl":null,"permalink":"/posts/2014-10-03-keepas-node/","section":"Posts","summary":"See https://github.com/gesellix/keepass-node\n➜ keepass-node git:(master) pwd /Users/miro/src/PLG/keepass-node Install # ➜ keepass-node git:(master) ✗ sudo npm install Password: \u003e dejavu@0.4.4 postinstall /Users/miro/src/PLG/keepass-node/node_modules/keepass.io/node_modules/dejavu \u003e node bin/post_install.js Saving runtime configuration in /Users/miro/src/PLG/keepass-node/node_modules/keepass.io/.dejavurc \u003e keepass.io@1.0.5 install /Users/miro/src/PLG/keepass-node/node_modules/keepass.io \u003e (node-gyp rebuild 2\u003e\u00261) || (echo 'DO NOT WORRY ABOUT THESE MESSAGES. KEEPASS.IO WILL FALLBACK TO SLOWER NODE.JS METHODS, SO THERE ARE NO LIMITATIONS EXCEPT SLOWER PERFORMANCE.'; exit 0) \\ Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. Agreeing to the Xcode/iOS license requires admin privileges, please re-run as root via sudo. gyp ERR! build error gyp ERR! stack Error: `make` failed with exit code: 69 gyp ERR! stack at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:267:23) gyp ERR! stack at ChildProcess.emit (events.js:98:17) gyp ERR! stack at Process.ChildProcess._handle.onexit (child_process.js:810:12) gyp ERR! System Darwin 13.4.0 gyp ERR! command \"node\" \"/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js\" \"rebuild\" gyp ERR! cwd /Users/miro/src/PLG/keepass-node/node_modules/keepass.io gyp ERR! node -v v0.10.31 gyp ERR! node-gyp -v v1.0.1 gyp ERR! not ok DO NOT WORRY ABOUT THESE MESSAGES. KEEPASS.IO WILL FALLBACK TO SLOWER NODE.JS METHODS, SO THERE ARE NO LIMITATIONS EXCEPT SLOWER PERFORMANCE. chai-as-promised@4.1.1 node_modules/chai-as-promised underscore@1.7.0 node_modules/underscore q@1.0.1 node_modules/q compression@1.1.0 node_modules/compression ├── bytes@1.0.0 ├── on-headers@1.0.0 ├── vary@1.0.0 ├── debug@2.0.0 (ms@0.6.2) ├── compressible@2.0.0 (mime-db@1.0.3) └── accepts@1.1.1 (negotiator@0.4.8, mime-types@2.0.2) chai@1.9.2 node_modules/chai ├── assertion-error@1.0.0 └── deep-eql@0.1.3 (type-detect@0.1.1) express@4.9.5 node_modules/express ├── merge-descriptors@0.0.2 ├── utils-merge@1.0.0 ├── fresh@0.2.4 ├── cookie@0.1.2 ├── escape-html@1.0.1 ├── range-parser@1.0.2 ├── cookie-signature@1.0.5 ├── media-typer@0.3.0 ├── vary@1.0.0 ├── finalhandler@0.2.0 ├── parseurl@1.3.0 ├── methods@1.1.0 ├── serve-static@1.6.3 ├── path-to-regexp@0.1.3 ├── depd@0.4.5 ├── qs@2.2.4 ├── debug@2.0.0 (ms@0.6.2) ├── on-finished@2.1.0 (ee-first@1.0.5) ├── etag@1.4.0 (crc@3.0.0) ├── proxy-addr@1.0.3 (forwarded@0.1.0, ipaddr.js@0.1.3) ├── send@0.9.3 (destroy@1.0.3, ms@0.6.2, mime@1.2.11) ├── type-is@1.5.2 (mime-types@2.0.2) └── accepts@1.1.1 (negotiator@0.4.8, mime-types@2.0.2) mocha@1.21.4 node_modules/mocha ├── diff@1.0.7 ├── growl@1.8.1 ├── commander@2.0.0 ├── mkdirp@0.3.5 ├── debug@2.0.0 (ms@0.6.2) ├── jade@0.26.3 (commander@0.6.1, mkdirp@0.3.0) └── glob@3.2.3 (inherits@2.0.1, graceful-fs@2.0.3, minimatch@0.2.14) body-parser@1.9.0 node_modules/body-parser ├── bytes@1.0.0 ├── media-typer@0.3.0 ├── raw-body@1.3.0 ├── depd@1.0.0 ├── qs@2.2.4 ├── iconv-lite@0.4.4 ├── on-finished@2.1.0 (ee-first@1.0.5) └── type-is@1.5.2 (mime-types@2.0.2) coveralls@2.11.2 node_modules/coveralls ├── lcov-parse@0.0.6 ├── log-driver@1.2.4 ├── request@2.40.0 (json-stringify-safe@5.0.0, forever-agent@0.5.2, aws-sign2@0.5.0, oauth-sign@0.3.0, stringstream@0.0.4, tunnel-agent@0.4.0, qs@1.0.2, node-uuid@1.4.1, mime-types@1.0.2, tough-cookie@0.12.1, form-data@0.1.4, http-signature@0.10.0, hawk@1.1.1) └── js-yaml@3.0.1 (esprima@1.0.4, argparse@0.1.15) istanbul@0.3.2 node_modules/istanbul ├── abbrev@1.0.5 ├── which@1.0.5 ├── nopt@3.0.1 ├── wordwrap@0.0.2 ├── once@1.3.1 (wrappy@1.0.1) ├── async@0.9.0 ├── resolve@0.7.4 ├── mkdirp@0.5.0 (minimist@0.0.8) ├── fileset@0.1.5 (minimatch@0.4.0, glob@3.2.11) ├── esprima@1.2.2 ├── escodegen@1.3.3 (estraverse@1.5.1, esutils@1.0.0, source-map@0.1.40, esprima@1.1.1) ├── handlebars@1.3.0 (optimist@0.3.7, uglify-js@2.3.6) └── js-yaml@3.2.2 (esprima@1.0.4, argparse@0.1.15) googleapis@1.0.14 node_modules/googleapis ├── async@0.9.0 ├── multipart-stream@1.0.0 (inherits@2.0.1, sandwich-stream@0.0.4) ├── request@2.40.0 (json-stringify-safe@5.0.0, aws-sign2@0.5.0, forever-agent@0.5.2, oauth-sign@0.3.0, stringstream@0.0.4, tunnel-agent@0.4.0, qs@1.0.2, node-uuid@1.4.1, mime-types@1.0.2, form-data@0.1.4, tough-cookie@0.12.1, http-signature@0.10.0, hawk@1.1.1) └── gapitoken@0.1.3 (jws@0.0.2) keepass.io@1.0.5 node_modules/keepass.io ├── async@0.9.0 ├── nan@1.2.0 ├── xml2js@0.4.4 (sax@0.6.0, xmlbuilder@2.4.4) └── dejavu@0.4.4 (amdefine@0.0.8, mout@0.4.0) ➜ keepass-node git:(master) Kinda weird to ignore errors, but anyway …\n","title":"Keepass-Node install","type":"post"},{"content":" With emails (Unix only) # ➜ dev1 git:(miro-ui) ✗ git log --raw | grep \u0026#34;^Author: \u0026#34; | sort | uniq -c 9 Author: Brendan Smith \u0026lt;Brendan.Smith@thinkwrap.com\u0026gt; 22 Author: Kai Cheng \u0026lt;kai.cheng@thinkwrap.com\u0026gt; 97 Author: Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; 49 Author: Training VM \u0026lt;training-vm@thinkwrap.com\u0026gt; 24 Author: Your Name \u0026lt;your.name@thinkwrap.com\u0026gt; Pure git # ➜ dev1 git:(miro-ui) ✗ git shortlog -sen 97 Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; 49 Training VM \u0026lt;training-vm@thinkwrap.com\u0026gt; 24 Your Name \u0026lt;your.name@thinkwrap.com\u0026gt; 22 Kai Cheng \u0026lt;kai.cheng@thinkwrap.com\u0026gt; 9 Brendan Smith \u0026lt;Brendan.Smith@thinkwrap.com\u0026gt; Mailmap option to consolidate the variety of authors # Before (no mailmap) # ... 609 milos hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; 361 brant maahs \u0026lt;brant.maahs@thinkwrap.com\u0026gt; 69 Sullivan Tseng \u0026lt;sullivantseng@gmail.com\u0026gt; 42 sullivan tseng \u0026lt;sullivan.tseng@thinkwrap.com\u0026gt; 17 milos.hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; 2 Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; ... Generating the mailman start\n➜ pal git:(master) ✗ git shortlog -se | awk -F\u0026rsquo;\\t\u0026rsquo; \u0026lsquo;{print $2,$3,$2,$3}\u0026rsquo; | sort \u0026gt; .mailmap\nAfter mailmap # Output with .mailmap file\n➜ pal git:(master) ✗ git shortlog -sen 626 Milos Hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; 361 Brant Maahs \u0026lt;brant.maahs@thinkwrap.com\u0026gt; 111 Sullivan Tseng \u0026lt;sullivan.tseng@thinkwrap.com\u0026gt; 2 Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; The .mailmap file\nMiro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; Sullivan Tseng \u0026lt;sullivan.tseng@thinkwrap.com\u0026gt; sullivan tseng \u0026lt;sullivan.tseng@thinkwrap.com\u0026gt; Sullivan Tseng \u0026lt;sullivan.tseng@thinkwrap.com\u0026gt; sullivan tseng \u0026lt;sullivantseng@gmail.com\u0026gt; Brant Maahs \u0026lt;brant.maahs@thinkwrap.com\u0026gt; brant maahs \u0026lt;brant.maahs@thinkwrap.com\u0026gt; Milos Hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; milos hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; Milos Hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; milos.hanzel \u0026lt;milos.hanzel@thinkwrap.com\u0026gt; ","date":"September 29, 2014","externalUrl":null,"permalink":"/posts/2014-09-29-gitbits/","section":"Posts","summary":"With emails (Unix only) # ➜ dev1 git:(miro-ui) ✗ git log --raw | grep \"^Author: \" | sort | uniq -c 9 Author: Brendan Smith \u003cBrendan.Smith@thinkwrap.com\u003e 22 Author: Kai Cheng \u003ckai.cheng@thinkwrap.com\u003e 97 Author: Miro Adamy \u003cmiro.adamy@thinkwrap.com\u003e 49 Author: Training VM \u003ctraining-vm@thinkwrap.com\u003e 24 Author: Your Name \u003cyour.name@thinkwrap.com\u003e Pure git # ➜ dev1 git:(miro-ui) ✗ git shortlog -sen 97 Miro Adamy \u003cmiro.adamy@thinkwrap.com\u003e 49 Training VM \u003ctraining-vm@thinkwrap.com\u003e 24 Your Name \u003cyour.name@thinkwrap.com\u003e 22 Kai Cheng \u003ckai.cheng@thinkwrap.com\u003e 9 Brendan Smith \u003cBrendan.Smith@thinkwrap.com\u003e Mailmap option to consolidate the variety of authors # Before (no mailmap) # ... 609 milos hanzel \u003cmilos.hanzel@thinkwrap.com\u003e 361 brant maahs \u003cbrant.maahs@thinkwrap.com\u003e 69 Sullivan Tseng \u003csullivantseng@gmail.com\u003e 42 sullivan tseng \u003csullivan.tseng@thinkwrap.com\u003e 17 milos.hanzel \u003cmilos.hanzel@thinkwrap.com\u003e 2 Miro Adamy \u003cmiro.adamy@thinkwrap.com\u003e ... Generating the mailman start\n","title":"Gitbits - Get committer lists","type":"post"},{"content":"Make sure the VBOx extensions are installed.\nGo here for details:\nAdd share # In VirtualBox, Device add transient shared folder:\nThis one has made available path /Users/Shared/ATG-11 under the name ATG-11\nMount it # sudo mount -t vboxsf ATG-11 /media $ ll /media/Unix/ total 19M drwxr-xr-x. 1 root 408 Sep 12 16:02 ATG11-1 drwxr-xr-x. 1 root 272 Sep 12 16:02 ATG11-docs -rw-rw-r--. 1 root 675 May 13 23:46 atg-platform-mac.userlibraries -rw-rw-r--. 1 root 787 May 13 23:17 atg-platform-vm.userlibraries -rwxr--r--. 1 root 19M Feb 15 2013 jrebel-5.1.3-nosetup.zip -rw-r--r--. 1 root 1020 May 15 15:36 jrebel.lic -rw-r--r--. 1 root 582 May 15 14:58 rebel.xml drwxr-xr-x. 1 root 272 Apr 6 01:33 security drwxr-xr-x. 1 root 306 Jun 9 22:34 servers -rwxr--r--. 1 root 349 Dec 17 2013 users.txt drwxr-xr-x. 1 root 340 Sep 3 16:10 xrebel ","date":"September 23, 2014","externalUrl":null,"permalink":"/posts/2014-09-23-shared-folder/","section":"Posts","summary":"Make sure the VBOx extensions are installed.\nGo here for details:\nAdd share # In VirtualBox, Device add transient shared folder:\nThis one has made available path /Users/Shared/ATG-11 under the name ATG-11\nMount it # sudo mount -t vboxsf ATG-11 /media $ ll /media/Unix/ total 19M drwxr-xr-x. 1 root 408 Sep 12 16:02 ATG11-1 drwxr-xr-x. 1 root 272 Sep 12 16:02 ATG11-docs -rw-rw-r--. 1 root 675 May 13 23:46 atg-platform-mac.userlibraries -rw-rw-r--. 1 root 787 May 13 23:17 atg-platform-vm.userlibraries -rwxr--r--. 1 root 19M Feb 15 2013 jrebel-5.1.3-nosetup.zip -rw-r--r--. 1 root 1020 May 15 15:36 jrebel.lic -rw-r--r--. 1 root 582 May 15 14:58 rebel.xml drwxr-xr-x. 1 root 272 Apr 6 01:33 security drwxr-xr-x. 1 root 306 Jun 9 22:34 servers -rwxr--r--. 1 root 349 Dec 17 2013 users.txt drwxr-xr-x. 1 root 340 Sep 3 16:10 xrebel","title":"How to access shared folder in Linux guest in VirtualBox","type":"post"},{"content":"","date":"September 23, 2014","externalUrl":null,"permalink":"/tags/virtualbox/","section":"Tags","summary":"","title":"Virtualbox","type":"tags"},{"content":" Question from email: # how do I merge 1 file from master -\u0026gt; LIVE\nAnswer # You cannot. Merge operation creates new commit that has 2 or more parents and will always join full histories of the branches.\nYou can however:\nreplicate all changes done in single commit to different branch - this is \u0026ldquo;cherry pick\u0026rdquo; take state of single file from different branch into current branch How to replicate all changes done in single commit to different branch - \u0026ldquo;cherry pick\u0026rdquo; # Say you have latest commit in master that contains change to two files you need.\n1.) You go to target branch - LIVE, make sure you have clean work tree\ngit checkout LIVE git status =\u0026gt; should show no changes\n2.) \u0026ldquo;cherry pick\u0026rdquo; the commit from master\ngit cherry-pick master\nThis will create new commit on LIVE that has same author, message etc as latest commit on master.\nOnly the files modified in the commit will be touched - and the state of these files will be identical to master\nNote # You can use any TREE-ISH expression in cherry pick - tag name, branch name, remote branch name or SHA1\nCherry pick will cause that \u0026ldquo;logically\u0026rdquo; same commit will exist twice in the project history (with different SHA1)\nOveruse may cause harder to understand project histories\nHow to take state of single file from different branch into current branch # Use case: I need exact version of the file \u0026lsquo;src/com/something/Important.java\u0026rsquo; from master to LIVE\nManual (stupid) version - DO NOT DO THAT # The only reason I mention this because I have seen people doing it,\n1). Go to master - git checkout master 2). save file to temp - cp 'src/com/something/Important.java' /tmp 3). Go to live - git checkout LIVE copy file back - cp /tmp/Important.java src/com/something/ Add and commit file - git add 'src/com/something/Important.java'; git commit -m \u0026quot;Copied file from master' Useful way # If you specify file path in \u0026lsquo;git checkout\u0026rsquo;, it will get only that file(s) and will also add these files to index - ready for commit\n1). Go to destination branch - LIVE\ngit checkout LIVE\nget the file from master git checkout master \u0026ndash; src/com/something/Important.java\nNow you can validate with git status that the file is modified and ready to committed\nCommit git commit -m \u0026ldquo;Copied file from master\u0026rsquo;\nDifference between cherry-pick and the single file transfer # The end effect of cherry pick for commit with single file and the second way is the same: the file in LIVE has same content as in master.\nDifference is that the second way does not indicate in any way that the file status is actually the same (commit has different author and no relation to original commit), while using cherry-pick this information is copied.\nNothing prevents you using the second approach for multiple file (as part of single commit) by repeating checkout – multiple times.\nBoth will make the history of the project a bit messier. Please always consider whether merge is not an option.\n","date":"September 22, 2014","externalUrl":null,"permalink":"/posts/2014-09-22-gitbit/","section":"Posts","summary":"Question from email: # how do I merge 1 file from master -\u003e LIVE\nAnswer # You cannot. Merge operation creates new commit that has 2 or more parents and will always join full histories of the branches.\nYou can however:\nreplicate all changes done in single commit to different branch - this is “cherry pick” take state of single file from different branch into current branch How to replicate all changes done in single commit to different branch - “cherry pick” # Say you have latest commit in master that contains change to two files you need.\n","title":"Git bit of the day","type":"post"},{"content":"","date":"September 16, 2014","externalUrl":null,"permalink":"/tags/elk/","section":"Tags","summary":"","title":"Elk","type":"tags"},{"content":"","date":"September 16, 2014","externalUrl":null,"permalink":"/tags/logs/","section":"Tags","summary":"","title":"Logs","type":"tags"},{"content":"","date":"September 16, 2014","externalUrl":null,"permalink":"/tags/logstash/","section":"Tags","summary":"","title":"Logstash","type":"tags"},{"content":"I have been trying to make this work for about 1.5 hr. Looks like there is open bug - https://logstash.jira.com/browse/LOGSTASH-703\nHelpful link: https://groups.google.com/forum/#!topic/logstash-users/sZM03po7HJE\nWhat should work:\ngrok { match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse severity\u0026#34;], match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse server IP\u0026#34;], match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse user\u0026#34;] } What needs to be done instead\nYou _should_ be able to do exactly what you listed at the bottom of your email, except that you\u0026#39;d need `break_on_match =\u0026gt; false` so that it would parse each snippet for each message instead of just parsing the first one that matches. Unfortunately, due to a bug (https://logstash.jira.com/browse/LOGSTASH-703), this doesn\u0026#39;t work when you\u0026#39;re matching against the same field in each match expression (\u0026#34;message\u0026#34; in your case). I was hoping to take a stab at fixing this bug (as several others have mentioned an interest in doing), but got distracted and haven\u0026#39;t done it yet. It shouldn\u0026#39;t be terribly hard to fix, just needs some time. As a work-around, the following should work, but unfortunately the way that your tag_on_failure will end up working will be different because you have multiple Grok filters that could fail independently. It\u0026#39;s probably slightly less efficient to do it this way because the event has to pass from one filter to the next through the pipeline, but my guess (based on absolutely no empirical data) is that it isn\u0026#39;t significantly slower because the same work would need to be done by Regex either way, there\u0026#39;s just more LogStash in the mix this way. grok { match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse severity\u0026#34;] } grok { match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse server IP\u0026#34;] } grok { match =\u0026gt; [\u0026#34;message\u0026#34;, \u0026#34;regex to parse user\u0026#34;] } ~Greg Mefford ","date":"September 16, 2014","externalUrl":null,"permalink":"/posts/2014-09-16-logstash-error/","section":"Posts","summary":"I have been trying to make this work for about 1.5 hr. Looks like there is open bug - https://logstash.jira.com/browse/LOGSTASH-703\nHelpful link: https://groups.google.com/forum/#!topic/logstash-users/sZM03po7HJE\nWhat should work:\ngrok { match =\u003e [\"message\", \"regex to parse severity\"], match =\u003e [\"message\", \"regex to parse server IP\"], match =\u003e [\"message\", \"regex to parse user\"] } What needs to be done instead\nYou _should_ be able to do exactly what you listed at the bottom of your email, except that you'd need `break_on_match =\u003e false` so that it would parse each snippet for each message instead of just parsing the first one that matches. Unfortunately, due to a bug (https://logstash.jira.com/browse/LOGSTASH-703), this doesn't work when you're matching against the same field in each match expression (\"message\" in your case). I was hoping to take a stab at fixing this bug (as several others have mentioned an interest in doing), but got distracted and haven't done it yet. It shouldn't be terribly hard to fix, just needs some time. As a work-around, the following should work, but unfortunately the way that your tag_on_failure will end up working will be different because you have multiple Grok filters that could fail independently. It's probably slightly less efficient to do it this way because the event has to pass from one filter to the next through the pipeline, but my guess (based on absolutely no empirical data) is that it isn't significantly slower because the same work would need to be done by Regex either way, there's just more LogStash in the mix this way. grok { match =\u003e [\"message\", \"regex to parse severity\"] } grok { match =\u003e [\"message\", \"regex to parse server IP\"] } grok { match =\u003e [\"message\", \"regex to parse user\"] } ~Greg Mefford","title":"logstash - known error","type":"post"},{"content":"","date":"September 9, 2014","externalUrl":null,"permalink":"/tags/documentation/","section":"Tags","summary":"","title":"Documentation","type":"tags"},{"content":"","date":"September 9, 2014","externalUrl":null,"permalink":"/tags/graphviz/","section":"Tags","summary":"","title":"Graphviz","type":"tags"},{"content":" Graphviz # This time using brew\n➜ DPS brew install graphviz ==\u0026gt; Downloading https://downloads.sf.net/project/machomebrew/Bottles/graphviz-2.38.0.mavericks.bottle.tar.gz ######################################################################## 100.0% ==\u0026gt; Pouring graphviz-2.38.0.mavericks.bottle.tar.gz 🍺 /usr/local/Cellar/graphviz/2.38.0: 469 files, 68M ➜ DPS dot -V dot - graphviz version 2.38.0 (20140413.2041) ➜ DPS Schema Spy # From http://sourceforge.net/projects/schemaspy/files/schemaspy/SchemaSpy%205.0.0/\nTo /opt/diagram\nRun:\ndiagram java -jar ./schemaSpy_5.0.0.jar -cp .:/Users/miro/lib/jdbc/mysql-connector-java-5.1.26-bin.jar -t mysql -o library -host localhost -u training -db training_dev01 -p training\nIt produces HTML documentation for tables\nSize is about 51 M for a small ATG install\nPlantUML # Also installed in /opt/diagram\nhttp://plantuml.sourceforge.net/running.html\nSee http://www.planttext.com\nCommand Line # You can also run PlantUML using the following command :java -jar plantuml.jar file1 file2 file3 This will look for @startuml into file1, file2 and file3. (For each diagram, it will create a .png file). For processing a whole directory, you can use: java -jar plantuml.jar \u0026#34;c:/directory1\u0026#34; \u0026#34;c:/directory2\u0026#34; This command will search for @startuml and @enduml into .c, .h, .cpp, .txt, .pu, .tex, .html, .htm or .java files of the c:/directory directory. (For each diagram, it will create a .png file). From Groovy # Since calling Java from Groovy is pretty simple, the only thinks to do is to copy PlantUML.jar file to the classpath (for exemple, ../Groovy/Groovy-1.7.6/lib directory).The following script print the current PlantUML version, and encode a URL:\nprintln net.sourceforge.plantuml.version.Version.version() println net.sourceforge.plantuml.code.TranscoderUtil.getDefaultTranscoder().encode(\u0026#34;Bob-\u0026gt;Alice:hello\u0026#34;) If you want to generate an image from a description: s = new net.sourceforge.plantuml.SourceStringReader(\u0026#34;@startuml\\nBob-\u0026gt;Alice:hello\\n@enduml\u0026#34;) FileOutputStream file = new FileOutputStream(\u0026#34;c:/testGroovy2.png\u0026#34;) s.generateImage(file); file.close() Examples: # @startuml start if (multiprocessor?) then (yes) fork :Treatment 1; fork again :Treatment 2; end fork else (monoproc) :Treatment 1; :Treatment 2; endif @enduml @startuml package \u0026#34;Some Group\u0026#34; { HTTP - [First Component] [Another Component] } node \u0026#34;Other Groups\u0026#34; { FTP - [Second Component] [First Component] --\u0026gt; FTP } cloud { [Example 1] } database \u0026#34;MySql\u0026#34; { folder \u0026#34;This is my folder\u0026#34; { [Folder 3] } frame \u0026#34;Foo\u0026#34; { [Frame 4] } } [Another Component] --\u0026gt; [Example 1] [Example 1] --\u0026gt; [Folder 3] [Folder 3] --\u0026gt; [Frame 4] @enduml ","date":"September 9, 2014","externalUrl":null,"permalink":"/posts/2014-09-09-redo-graph/","section":"Posts","summary":"Graphviz # This time using brew\n➜ DPS brew install graphviz ==\u003e Downloading https://downloads.sf.net/project/machomebrew/Bottles/graphviz-2.38.0.mavericks.bottle.tar.gz ######################################################################## 100.0% ==\u003e Pouring graphviz-2.38.0.mavericks.bottle.tar.gz 🍺 /usr/local/Cellar/graphviz/2.38.0: 469 files, 68M ➜ DPS dot -V dot - graphviz version 2.38.0 (20140413.2041) ➜ DPS Schema Spy # From http://sourceforge.net/projects/schemaspy/files/schemaspy/SchemaSpy%205.0.0/\nTo /opt/diagram\nRun:\ndiagram java -jar ./schemaSpy_5.0.0.jar -cp .:/Users/miro/lib/jdbc/mysql-connector-java-5.1.26-bin.jar -t mysql -o library -host localhost -u training -db training_dev01 -p training\n","title":"Recreate txt base graph generator","type":"post"},{"content":"Source of the fix is https://github.com/jc7447/BetterDynAdmin. This is to capture the installation process and provide backup in case the tool disappears.\nThe pages generated by DynAdmin are actually not coming from a JSP or JHTML pages. The HTML you see is generated by hardcoded servlets. Each Nucleus component has assigned Admin servet, which is called when DynAdmin is trying to render the page.\nThe improvent here are user scripts - running inside Firefox or Chrome, utilizing infrastructure provided by Greasemonkey extension (FF) or Tampermonkey (Chrome).\nInstallation - Chrome # Download and install Tampermonkey - https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo\nIt will show as new icon. Click the icon:\nselect Add New Script, use the URL https://raw.githubusercontent.com/jc7447/bda/master/bda.user.js (also see bda.user.js local copy attachment)\nMake sure that in settings the /dyn/admin is selected - this is what triggers the script run\n","date":"September 4, 2014","externalUrl":null,"permalink":"/posts/2014-09-04-better-dynadmin/","section":"Posts","summary":"Source of the fix is https://github.com/jc7447/BetterDynAdmin. This is to capture the installation process and provide backup in case the tool disappears.\nThe pages generated by DynAdmin are actually not coming from a JSP or JHTML pages. The HTML you see is generated by hardcoded servlets. Each Nucleus component has assigned Admin servet, which is called when DynAdmin is trying to render the page.\nThe improvent here are user scripts - running inside Firefox or Chrome, utilizing infrastructure provided by Greasemonkey extension (FF) or Tampermonkey (Chrome).\n","title":"Better dynadmin","type":"post"},{"content":" Symptoms # restarting after kill -9 of CSC instance does not succeed. The server never starts, the WAR files are not deployed properly, socket 8080 is open but nobody answers (not even with wget on localhost).\nThe exception: # \u0026#34;main\u0026#34; prio=10 tid=0x0000000051a39000 nid=0x30fb in Object.wait() [0x00002b5df9d6c000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u0026lt;0x00000007e36ae9d0\u0026gt; (a atg.service.lockmanager.ClientLockEntry) at atg.service.lockmanager.ClientLockEntry.acquireWriteLock(ClientLockEntry.java:399) - locked \u0026lt;0x00000007e36ae9d0\u0026gt; (a atg.service.lockmanager.ClientLockEntry) at atg.service.lockmanager.ClientLockManager.acquireWriteLock(ClientLockManager.java:1137) at atg.repository.search.indexing.ConfigStatePersister.acquireLock(ConfigStatePersister.java:1844) at atg.repository.search.indexing.ConfigStatePersister$IndexingReadLockedTransactionAction.doWithTransaction(ConfigStatePersister.java:2083) at atg.repository.search.indexing.ConfigStatePersister.releaseAllConfigurations(ConfigStatePersister.java:1545) at atg.repository.search.indexing.ConfigStatePersister.performAction(ConfigStatePersister.java:1775) at atg.nucleus.Nucleus.performPostStartupActions(Nucleus.java:4336) at atg.nucleus.Nucleus.performPostStartupActions(Nucleus.java:4323) at atg.nucleus.Nucleus.\u0026lt;init\u0026gt;(Nucleus.java:954) at atg.nucleus.Nucleus.\u0026lt;init\u0026gt;(Nucleus.java:717) at atg.nucleus.Nucleus.startNucleusCheckLicense(Nucleus.java:4144) at atg.nucleus.servlet.NucleusServlet.initBigEarNucleus(NucleusServlet.java:1234) at atg.nucleus.servlet.NucleusServlet.init(NucleusServlet.java:443) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1048) - locked \u0026lt;0x0000000781734f48\u0026gt; (a org.apache.catalina.core.StandardWrapper) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:950) - locked \u0026lt;0x0000000781734f48\u0026gt; (a org.apache.catalina.core.StandardWrapper) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4122) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4417) - locked \u0026lt;0x0000000781733e18\u0026gt; (a org.apache.catalina.core.StandardContext) at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:321) at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145) at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461) - locked \u0026lt;0x0000000780878058\u0026gt; (a org.jboss.web.tomcat.service.deployers.TomcatDeployment) at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118) - locked \u0026lt;0x0000000780878038\u0026gt; (a org.jboss.web.deployers.WebModule) at org.jboss.web.deployers.WebModule.start(WebModule.java:97) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157) at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96) at org.jboss.mx.server.Invocation.invoke(Invocation.java:88) at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264) at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668) at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206) at $Proxy38.start(Unknown Source) at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42) at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37) at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62) at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71) at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:297) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556) at org.jboss.system.ServiceController.doChange(ServiceController.java:688) at org.jboss.system.ServiceController.start(ServiceController.java:460) at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163) at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99) at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46) at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62) at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:55) at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:179) at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1454) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1172) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1193) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1225) at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1113) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556) at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:789) at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:699) at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117) at org.jboss.system.server.profileservice.repository.ProfileDeployAction.install(ProfileDeployAction.java:70) at org.jboss.system.server.profileservice.repository.AbstractProfileAction.install(AbstractProfileAction.java:53) at org.jboss.system.server.profileservice.repository.AbstractProfileService.install(AbstractProfileService.java:403) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:778) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:543) at org.jboss.system.server.profileservice.repository.AbstractProfileService.registerProfile(AbstractProfileService.java:308) at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:256) at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:461) at org.jboss.Main.boot(Main.java:221) at org.jboss.Main$1.run(Main.java:556) at java.lang.Thread.run(Thread.java:662) What is going on: # In the run of deployment, JBoss is starting context, hands over control to NucleusServlet init. Nucleus is trying to get write access lock and hangs there forever, while WAR deployment and all subsequent deployment never completes.\nReally ? Is this the best you can do ?\nWhy would not JBOSS time out the loadServlet action, catch exception and continue deploying the other WAR file ?\nFrom Nucleus point of view, depending on presence (and even worse WAITING for it) of external service to start up is not very bright idea. It would be much more helpful throw exception indicating there is not a LockServer available and abort the deployment.\nJust hanging there is plain stupid.\nTo add to the confusion, some of the service from the WAR file that is deployed are running and spitting exceptions to log file:\n21:01:55,410 ERROR [/atg/ticketing/scheduled/UnsuspendTicketPeriodicService] Error while processing item ticket:105397 atg.ticketing.TicketingException: Cannot unsuspend ticket because it is not pending. at atg.ticketing.TicketingManager$7.doInTransaction(TicketingManager.java:2164) at atg.dtm.TransactionUtil$TypedTransactionAction.doWithTransaction(TransactionUtil.java:73) at atg.ticketing.TicketingManager.unsuspendTicket(TicketingManager.java:2155) at atg.ticketing.scheduled.UnsuspendTicketPeriodicService.processDueItem(UnsuspendTicketPeriodicService.java:116) at atg.ticketing.scheduled.TicketingPeriodicService$1.doInTransaction(TicketingPeriodicService.java:193) at atg.dtm.TransactionUtil$TypedTransactionAction.doWithTransaction(TransactionUtil.java:73) at atg.ticketing.scheduled.TicketingPeriodicService.performScheduledTask(TicketingPeriodicService.java:191) at atg.ticketing.scheduled.TicketingPeriodicService.performScheduledTask(TicketingPeriodicService.java:165) at atg.service.scheduler.ScheduledJob.runJobs(ScheduledJob.java:441) at atg.service.scheduler.Scheduler$2handler.run(Scheduler.java:760) Again - why should the scheduled services be started BEFORE we know the EAR/WAR has actually successfully deployed ? These are not the services required for the boot !!!\n","date":"September 3, 2014","externalUrl":null,"permalink":"/posts/2014-09-03-atg-rant/","section":"Posts","summary":"Symptoms # restarting after kill -9 of CSC instance does not succeed. The server never starts, the WAR files are not deployed properly, socket 8080 is open but nobody answers (not even with wget on localhost).\nThe exception: # \"main\" prio=10 tid=0x0000000051a39000 nid=0x30fb in Object.wait() [0x00002b5df9d6c000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on \u003c0x00000007e36ae9d0\u003e (a atg.service.lockmanager.ClientLockEntry) at atg.service.lockmanager.ClientLockEntry.acquireWriteLock(ClientLockEntry.java:399) - locked \u003c0x00000007e36ae9d0\u003e (a atg.service.lockmanager.ClientLockEntry) at atg.service.lockmanager.ClientLockManager.acquireWriteLock(ClientLockManager.java:1137) at atg.repository.search.indexing.ConfigStatePersister.acquireLock(ConfigStatePersister.java:1844) at atg.repository.search.indexing.ConfigStatePersister$IndexingReadLockedTransactionAction.doWithTransaction(ConfigStatePersister.java:2083) at atg.repository.search.indexing.ConfigStatePersister.releaseAllConfigurations(ConfigStatePersister.java:1545) at atg.repository.search.indexing.ConfigStatePersister.performAction(ConfigStatePersister.java:1775) at atg.nucleus.Nucleus.performPostStartupActions(Nucleus.java:4336) at atg.nucleus.Nucleus.performPostStartupActions(Nucleus.java:4323) at atg.nucleus.Nucleus.\u003cinit\u003e(Nucleus.java:954) at atg.nucleus.Nucleus.\u003cinit\u003e(Nucleus.java:717) at atg.nucleus.Nucleus.startNucleusCheckLicense(Nucleus.java:4144) at atg.nucleus.servlet.NucleusServlet.initBigEarNucleus(NucleusServlet.java:1234) at atg.nucleus.servlet.NucleusServlet.init(NucleusServlet.java:443) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1048) - locked \u003c0x0000000781734f48\u003e (a org.apache.catalina.core.StandardWrapper) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:950) - locked \u003c0x0000000781734f48\u003e (a org.apache.catalina.core.StandardWrapper) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4122) at org.apache.catalina.core.StandardContext.start(StandardContext.java:4417) - locked \u003c0x0000000781733e18\u003e (a org.apache.catalina.core.StandardContext) at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeployInternal(TomcatDeployment.java:321) at org.jboss.web.tomcat.service.deployers.TomcatDeployment.performDeploy(TomcatDeployment.java:145) at org.jboss.web.deployers.AbstractWarDeployment.start(AbstractWarDeployment.java:461) - locked \u003c0x0000000780878058\u003e (a org.jboss.web.tomcat.service.deployers.TomcatDeployment) at org.jboss.web.deployers.WebModule.startModule(WebModule.java:118) - locked \u003c0x0000000780878038\u003e (a org.jboss.web.deployers.WebModule) at org.jboss.web.deployers.WebModule.start(WebModule.java:97) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157) at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96) at org.jboss.mx.server.Invocation.invoke(Invocation.java:88) at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264) at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668) at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206) at $Proxy38.start(Unknown Source) at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42) at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37) at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62) at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71) at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:297) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556) at org.jboss.system.ServiceController.doChange(ServiceController.java:688) at org.jboss.system.ServiceController.start(ServiceController.java:460) at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163) at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99) at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46) at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62) at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:55) at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:179) at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1454) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1172) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1193) at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1225) at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1113) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:826) at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:556) at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:789) at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:699) at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117) at org.jboss.system.server.profileservice.repository.ProfileDeployAction.install(ProfileDeployAction.java:70) at org.jboss.system.server.profileservice.repository.AbstractProfileAction.install(AbstractProfileAction.java:53) at org.jboss.system.server.profileservice.repository.AbstractProfileService.install(AbstractProfileService.java:403) at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1652) at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:938) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082) at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:988) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:778) at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:543) at org.jboss.system.server.profileservice.repository.AbstractProfileService.registerProfile(AbstractProfileService.java:308) at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:256) at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:461) at org.jboss.Main.boot(Main.java:221) at org.jboss.Main$1.run(Main.java:556) at java.lang.Thread.run(Thread.java:662) What is going on: # In the run of deployment, JBoss is starting context, hands over control to NucleusServlet init. Nucleus is trying to get write access lock and hangs there forever, while WAR deployment and all subsequent deployment never completes.\n","title":"ATG + JBoss rant","type":"post"},{"content":" Show branches and tags in log # git log \u0026ndash;oneline \u0026ndash;decorate\nEven better - all branches with graph # git log \u0026ndash;oneline \u0026ndash;decorate \u0026ndash;all \u0026ndash;graph\nHighlight words instead of lines # git diff \u0026ndash;word-diff HEAD~~~ HEAD~~\nAlso works in git log -p and git show\nBetter status # git status -sb\nCompare with gs == git status\nFind a name # ➜ simstore-atg git:(master) ✗ git name-rev 2643908 2643908 remotes/origin/HEAD~2 ➜ simstore-atg git:(master) ✗ git name-rev --name-only 2643908 remotes/origin/HEAD~2 ➜ simstore-atg git:(master) ✗ git name-rev --name-only 188fcd6 LIVE ➜ simstore-atg git:(master) ✗ git name-rev --name-only 73c762c remotes/origin/2013-10-22-LIVE~3 Find which branch has a commit # ➜ simstore-atg git:(master) ✗ git branch --contains 73c762c LIVE LIVE-140430 LIVE2 LIVE3 LIVE4 PATCH-ORS-140605 PATCH-ORS-140616 feature_us_shipping * master ➜ simstore-atg git:(master) ✗ git branch --contains 188fcd6 LIVE ➜ simstore-atg git:(master) ✗ git branch --contains 2643908 ➜ simstore-atg git:(master) ✗ git pull Updating ed81557..220a6a7 Fast-forward .... ➜ simstore-atg git:(master) ✗ git branch --contains 2643908 * master The NO RESULT from 2643908 was caused by the fact that this commit was present only in origin/master, not yet merged into local master. After pull, it does show\nOf course, I could have used \u0026lsquo;-a\u0026rsquo; flag to show all branches\n➜ simstore-atg git:(master) ✗ git branch -a --contains 2643908 * master remotes/origin/HEAD -\u0026gt; origin/master remotes/origin/master Show which commit contains message # git show :/SIMWEB-700\nFor multiple commits: all commits related to ticket (searches THE COMMIT MESSAGE)\ngit last --grep SIMWEB-867 ➜ simstore-atg git:(master) ✗ git last\u0026lt;TAB\u0026gt; last -- alias for \u0026#39;log --pretty=format:\u0026#34;%h %ad | %s%d [%an]\u0026#34; --date=short\u0026#39; Searches the DIFF - not the message - for SimpleDateFormat\ngit log \u0026ndash;word-diff \u0026ndash;stat -GSimpleDateFormat\nThe word SimpleDateFormat is NOT in message, but in diff:\nIf we inspect the commit diff for one of the commits:\n➜ simstore-atg git:(master) ✗ git log -1 -p 2fc121c7e75c6f5aeb57b25030e5fa9896e29a88 | grep -n SimpleDateFormat 200:-import java.text.SimpleDateFormat; 279:- SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); 307:+import java.text.SimpleDateFormat; 405:+ SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); ➜ simstore-atg git:(master) ✗ ","date":"September 3, 2014","externalUrl":null,"permalink":"/posts/2014-09-03-gitbits/","section":"Posts","summary":"Show branches and tags in log # git log –oneline –decorate\nEven better - all branches with graph # git log –oneline –decorate –all –graph\nHighlight words instead of lines # git diff –word-diff HEAD~~~ HEAD~~\n","title":"Few gitbits","type":"post"},{"content":"","date":"August 28, 2014","externalUrl":null,"permalink":"/tags/elastic/","section":"Tags","summary":"","title":"Elastic","type":"tags"},{"content":"","date":"August 28, 2014","externalUrl":null,"permalink":"/tags/search/","section":"Tags","summary":"","title":"Search","type":"tags"},{"content":"","date":"August 28, 2014","externalUrl":null,"permalink":"/tags/tutorial/","section":"Tags","summary":"","title":"Tutorial","type":"tags"},{"content":" Running elastic # (see Elastic search and Kibana - getting started)\nUse case: building a employee directory for Megacorp\neach document - type of \u0026rsquo;employee' everything in megacorp index Populating # # Delete the `megacorp` index in case it already exists DELETE /megacorp # Index document 1, type \u0026#34;employee\u0026#34;, in the # \u0026#34;megacorp\u0026#34; index PUT /megacorp/employee/1 { \u0026#34;first_name\u0026#34; : \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34; : \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34; : 25, \u0026#34;about\u0026#34; : \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } # Index two more documents PUT /megacorp/employee/2 { \u0026#34;first_name\u0026#34; : \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34; : \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34; : 32, \u0026#34;about\u0026#34; : \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } PUT /megacorp/employee/3 { \u0026#34;first_name\u0026#34; : \u0026#34;Douglas\u0026#34;, \u0026#34;last_name\u0026#34; : \u0026#34;Fir\u0026#34;, \u0026#34;age\u0026#34; : 35, \u0026#34;about\u0026#34;: \u0026#34;I like to build cabinets\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;forestry\u0026#34; ] } In server\n2014-08-28 13:58:02,769][INFO ][cluster.metadata ] [Sea Urchin] [megacorp] creating index, cause [auto(index api)], shards [5]/[1], mappings [] [2014-08-28 13:58:02,858][INFO ][cluster.metadata ] [Sea Urchin] [megacorp] update_mapping [employee] (dynamic) [2014-08-28 13:58:16,319][INFO ][cluster.metadata ] [Sea Urchin] [megacorp] deleting index [2014-08-28 13:58:18,891][INFO ][cluster.metadata ] [Sea Urchin] [megacorp] creating index, cause [auto(index api)], shards [5]/[1], mappings [] [2014-08-28 13:58:18,964][INFO ][cluster.metadata ] [Sea Urchin] [megacorp] update_mapping [employee] (dynamic) Retrieve # # Retrieve the updated document GET /megacorp/employee/1 { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } } Get all # # Search for all employees in the megacorp index: # By default, returns to 10 results GET /megacorp/employee/_search URL based search # # Search for all employees in the megacorp index # who have \u0026#34;Smith\u0026#34; in the last_name field GET /megacorp/employee/_search?q=last_name:Smith Query DSL # # Same query as above, but using the Query DSL GET /megacorp/employee/_search { \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;last_name\u0026#34;: \u0026#34;smith\u0026#34; } } } Filtering # Combines filter (age \u0026gt; 30) and query within filter (last name = Smith)\n# Find all employees whose `last_name` is Smith # and who are older than 30 GET /megacorp/employee/_search { \u0026#34;query\u0026#34; : { \u0026#34;filtered\u0026#34; : { \u0026#34;filter\u0026#34; : { \u0026#34;range\u0026#34; : { \u0026#34;age\u0026#34; : { \u0026#34;gt\u0026#34; : 30 } } }, \u0026#34;query\u0026#34; : { \u0026#34;match\u0026#34; : { \u0026#34;last_name\u0026#34; : \u0026#34;smith\u0026#34; } } } } } { \u0026#34;took\u0026#34;: 5, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.30685282, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_score\u0026#34;: 0.30685282, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 32, \u0026#34;about\u0026#34;: \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } } ] } } Text queries with OR # # Find all employees who enjoy \u0026#34;rock\u0026#34; or \u0026#34;climbing\u0026#34; GET /megacorp/employee/_search { \u0026#34;query\u0026#34; : { \u0026#34;match\u0026#34; : { \u0026#34;about\u0026#34; : \u0026#34;rock climbing\u0026#34; } } } Note the OR and how relevance is different\n{ \u0026#34;took\u0026#34;: 5, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;max_score\u0026#34;: 0.16273327, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.16273327, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_score\u0026#34;: 0.016878016, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 32, \u0026#34;about\u0026#34;: \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } } ] } } Elasticsearch can search within full text fields and return the most relevant results first.\nExact phrase # # Find all employees who enjoy \u0026#34;rock climbing\u0026#34; GET /megacorp/employee/_search { \u0026#34;query\u0026#34; : { \u0026#34;match_phrase\u0026#34; : { \u0026#34;about\u0026#34; : \u0026#34;rock climbing\u0026#34; } } } Gives back higher score\n{ \u0026#34;took\u0026#34;: 4, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.23013961, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.23013961, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } } ] } } Highlight # GET /megacorp/employee/_search { \u0026#34;query\u0026#34; : { \u0026#34;match_phrase\u0026#34; : { \u0026#34;about\u0026#34; : \u0026#34;rock climbing\u0026#34; } }, \u0026#34;highlight\u0026#34;: { \u0026#34;fields\u0026#34; : { \u0026#34;about\u0026#34; : {} } } } See the HTML highlight # { \u0026#34;took\u0026#34;: 18, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.23013961, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.23013961, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] }, \u0026#34;highlight\u0026#34;: { \u0026#34;about\u0026#34;: [ \u0026#34;I love to go \u0026lt;em\u0026gt;rock\u0026lt;/em\u0026gt; \u0026lt;em\u0026gt;climbing\u0026lt;/em\u0026gt;\u0026#34; ] } } ] } } Analytics # not recalculated on the fly # Calculate the most popular interests for all employees GET /megacorp/employee/_search { \u0026#34;aggs\u0026#34;: { \u0026#34;all_interests\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;interests\u0026#34; } } } } { \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 3, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Douglas\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Fir\u0026#34;, \u0026#34;age\u0026#34;: 35, \u0026#34;about\u0026#34;: \u0026#34;I like to build cabinets\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;forestry\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 32, \u0026#34;about\u0026#34;: \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } } ] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;all_interests\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;music\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;forestry\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 }, { \u0026#34;key\u0026#34;: \u0026#34;sports\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } } } Can be combined with Query\n# Calculate the most popular interests for # employees named \u0026#34;Smith\u0026#34; GET /megacorp/employee/_search { \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;last_name\u0026#34;: \u0026#34;smith\u0026#34; } }, \u0026#34;aggs\u0026#34;: { \u0026#34;all_interests\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;interests\u0026#34; } } } } REsult\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;max_score\u0026#34;: 0.30685282, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.30685282, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_score\u0026#34;: 0.30685282, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 32, \u0026#34;about\u0026#34;: \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } } ] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;all_interests\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;music\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;sports\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } } } Aggregation with average computation:\nHierarchical roll-ups # # Calculate the average age of employee per interest GET /megacorp/employee/_search { \u0026#34;aggs\u0026#34; : { \u0026#34;all_interests\u0026#34; : { \u0026#34;terms\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;interests\u0026#34; }, \u0026#34;aggs\u0026#34; : { \u0026#34;avg_age\u0026#34; : { \u0026#34;avg\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;age\u0026#34; } } } } } } { \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 3, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Douglas\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Fir\u0026#34;, \u0026#34;age\u0026#34;: 35, \u0026#34;about\u0026#34;: \u0026#34;I like to build cabinets\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;forestry\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;John\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 25, \u0026#34;about\u0026#34;: \u0026#34;I love to go rock climbing\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;sports\u0026#34;, \u0026#34;music\u0026#34; ] } }, { \u0026#34;_index\u0026#34;: \u0026#34;megacorp\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;employee\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;first_name\u0026#34;: \u0026#34;Jane\u0026#34;, \u0026#34;last_name\u0026#34;: \u0026#34;Smith\u0026#34;, \u0026#34;age\u0026#34;: 32, \u0026#34;about\u0026#34;: \u0026#34;I like to collect rock albums\u0026#34;, \u0026#34;interests\u0026#34;: [ \u0026#34;music\u0026#34; ] } } ] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;all_interests\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;music\u0026#34;, \u0026#34;doc_count\u0026#34;: 2, \u0026#34;avg_age\u0026#34;: { \u0026#34;value\u0026#34;: 28.5 } }, { \u0026#34;key\u0026#34;: \u0026#34;forestry\u0026#34;, \u0026#34;doc_count\u0026#34;: 1, \u0026#34;avg_age\u0026#34;: { \u0026#34;value\u0026#34;: 35 } }, { \u0026#34;key\u0026#34;: \u0026#34;sports\u0026#34;, \u0026#34;doc_count\u0026#34;: 1, \u0026#34;avg_age\u0026#34;: { \u0026#34;value\u0026#34;: 25 } } ] } } } Experiments with loaded logs # GET /_all/logs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } GET /_all/logs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;level\u0026#34;: \u0026#34;ERROR\u0026#34; } } } Retrieve document: # GET /website/blog/123?pretty # only source, no metadata GET /website/blog/123/_source # only some fields GET /website/blog/123?_source=title,text Existence check # curl -i -XHEAD http://localhost:9200/website/blog/123 HTTP/1.1 200 OK Content-Type: text/plain; charset=UTF-8 Content-Length: 0 curl -i -XHEAD http://localhost:9200/website/blog/124 HTTP/1.1 404 Not Found Content-Type: text/plain; charset=UTF-8 Content-Length: 0 Update # whole doc - same index API\nPUT /website/blog/123 { \u0026#34;title\u0026#34;: \u0026#34;My first blog entry\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;I am starting to get the hang of this...\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2014/01/02\u0026#34; } # note new version, created false { \u0026#34;_index\u0026#34; : \u0026#34;website\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;blog\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;123\u0026#34;, \u0026#34;_version\u0026#34; : 2, \u0026#34;created\u0026#34;: false } Internally, Elasticsearch has marked the old document as deleted and added an entirely new document. The old version of the document doesn’t disappear immediately, although you won’t be able to access it. Elasticsearch cleans up deleted documents in the background as you continue to index more data.\nCreate # let the ES generate new ID\nPOST /website/blog/ { ... } # or force our ID but want to allow create only, not update PUT /website/blog/123?op_type=create { ... } # another way PUT /website/blog/123/_create { ... } # will error if it exists: { \u0026#34;error\u0026#34; : \u0026#34;DocumentAlreadyExistsException[[website][4] [blog][123]: document already exists]\u0026#34;, \u0026#34;status\u0026#34; : 409 } Delete # GET /logstash-2014.08.21/_search { \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;logstash-2014.08.21\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;logs\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;cjV9RKSBS5K5pRh7QlfllQ\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;message\u0026#34;: \u0026#34;asdasdasd asasdasd\u0026#34;, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;: \u0026#34;2014-08-21T21:41:46.016Z\u0026#34;, \u0026#34;host\u0026#34;: \u0026#34;Miros-MacBook-Pro-2.local\u0026#34; } } ] } } DELETE /logstash-2014.08.21/logs/cjV9RKSBS5K5pRh7QlfllQ { \u0026#34;found\u0026#34;: true, \u0026#34;_index\u0026#34;: \u0026#34;logstash-2014.08.21\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;logs\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;cjV9RKSBS5K5pRh7QlfllQ\u0026#34;, \u0026#34;_version\u0026#34;: 2 } GET /logstash-2014.08.21/_search { \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 0, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] } } afterwards, index still exist:\n➜ elasticsearch-1.3.2 es -v indices status name pri rep size bytes docs yellow logstash-2014.08.21 5 1 11946 0 yellow shakespeare 5 1 19087632 111396 yellow logstash-2014.08.22 5 1 47220 18 yellow megacorp 5 1 11067 3 yellow logstash-2014.08.27 5 1 24996521 14490 yellow logstash-2014.08.28 5 1 36012778 22645 yellow kibana-int 5 1 36253 3 yellow .marvel-kibana 5 1 3586 1 yellow .marvel-2014.08.28 1 1 16360673 7980 yellow logstash-2013.12.11 5 1 9943 1 ","date":"August 28, 2014","externalUrl":null,"permalink":"/posts/2014-08-28-elastic-tutorial/","section":"Posts","summary":"Running elastic # (see Elastic search and Kibana - getting started)\nUse case: building a employee directory for Megacorp\neach document - type of ’employee' everything in megacorp index Populating # # Delete the `megacorp` index in case it already exists DELETE /megacorp # Index document 1, type \"employee\", in the # \"megacorp\" index PUT /megacorp/employee/1 { \"first_name\" : \"John\", \"last_name\" : \"Smith\", \"age\" : 25, \"about\" : \"I love to go rock climbing\", \"interests\": [ \"sports\", \"music\" ] } # Index two more documents PUT /megacorp/employee/2 { \"first_name\" : \"Jane\", \"last_name\" : \"Smith\", \"age\" : 32, \"about\" : \"I like to collect rock albums\", \"interests\": [ \"music\" ] } PUT /megacorp/employee/3 { \"first_name\" : \"Douglas\", \"last_name\" : \"Fir\", \"age\" : 35, \"about\": \"I like to build cabinets\", \"interests\": [ \"forestry\" ] } In server\n","title":"Tutorial on Elastic","type":"post"},{"content":"#Installation:\nSee curl -L -O http://download.elasticsearch.org/PATH/TO/VERSION.zip unzip elasticsearch-$VERSION.zip cd elasticsearch-$VERSION Marvel is management plugin - console about cluster. Install:\n./bin/plugin -i elasticsearch/marvel/latest # disable data collection for local cluster echo \u0026#39;marvel.agent.enabled: false\u0026#39; \u0026gt;\u0026gt; ./config/elasticsearch.yml Test # Startup log:\n➜ elasticsearch-1.3.2 bin/elasticsearch [2014-08-27 11:17:08,325][INFO ][node ] [Joe Fixit] version[1.3.2], pid[59610], build[dee175d/2014-08-13T14:29:30Z] [2014-08-27 11:17:08,325][INFO ][node ] [Joe Fixit] initializing ... [2014-08-27 11:17:08,338][INFO ][plugins ] [Joe Fixit] loaded [marvel], sites [marvel, kopf] [2014-08-27 11:17:10,905][INFO ][marvel.agent ] [Joe Fixit] collecting disabled by settings [2014-08-27 11:17:11,020][INFO ][node ] [Joe Fixit] initialized [2014-08-27 11:17:11,021][INFO ][node ] [Joe Fixit] starting ... [2014-08-27 11:17:11,131][INFO ][transport ] [Joe Fixit] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.179.121:9300]} [2014-08-27 11:17:11,148][INFO ][discovery ] [Joe Fixit] elasticsearch/nNgRXlHARHCPutTq7dZXWg [2014-08-27 11:17:14,160][INFO ][cluster.service ] [Joe Fixit] new_master [Joe Fixit][nNgRXlHARHCPutTq7dZXWg][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9300]], reason: zen-disco-join (elected_as_master) [2014-08-27 11:17:14,181][INFO ][http ] [Joe Fixit] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.179.121:9200]} [2014-08-27 11:17:14,181][INFO ][node ] [Joe Fixit] started [2014-08-27 11:17:14,726][INFO ][gateway ] [Joe Fixit] recovered [4] indices into cluster_state [2014-08-27 11:18:00,491][INFO ][cluster.service ] [Joe Fixit] added {[logstash-Miros-MacBook-Pro-2.local-59618-4086][Eh5YjUFxSIWIn4xK45xu0w][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9301]]{client=true, data=false},}, reason: zen-disco-receive(join from node[[logstash-Miros-MacBook-Pro-2.local-59618-4086][Eh5YjUFxSIWIn4xK45xu0w][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9301]]{client=true, data=false}]) Installed some pluggins - marvel, kopf ... ➜ ~ curl \u0026#39;http://localhost:9200/?pretty\u0026#39; { \u0026#34;status\u0026#34; : 200, \u0026#34;name\u0026#34; : \u0026#34;Sea Urchin\u0026#34;, \u0026#34;version\u0026#34; : { \u0026#34;number\u0026#34; : \u0026#34;1.3.2\u0026#34;, \u0026#34;build_hash\u0026#34; : \u0026#34;dee175dbe2f254f3f26992f5d7591939aaefd12f\u0026#34;, \u0026#34;build_timestamp\u0026#34; : \u0026#34;2014-08-13T14:29:30Z\u0026#34;, \u0026#34;build_snapshot\u0026#34; : false, \u0026#34;lucene_version\u0026#34; : \u0026#34;4.9\u0026#34; }, \u0026#34;tagline\u0026#34; : \u0026#34;You Know, for Search\u0026#34; } The sense console allows to avoid using curl and do it from browser: - \u0026lt;http://localhost:9200/_plugin/marvel/sense/ \u0026gt;\nCluster # same name in cluster.name, default\n➜ elasticsearch-1.3.2 cat config/elasticsearch.yml | grep cluster.name #cluster.name: elasticsearch Node names are generated, often funny\nSea Urchin Franz Kafka ➜ elasticsearch-1.3.2 grep -r \u0026#39;initializing ...\u0026#39; logs/ logs//elasticsearch.log:[2014-08-28 00:00:32,437][INFO ][node ] [Thing] initializing ... logs//elasticsearch.log:[2014-08-28 00:02:01,637][INFO ][node ] [Stacy X] initializing ... logs//elasticsearch.log:[2014-08-28 00:21:50,121][INFO ][node ] [Ursa Major] initializing ... logs//elasticsearch.log:[2014-08-28 10:32:37,790][INFO ][node ] [Sea Urchin] initializing ... logs//elasticsearch.log.2014-08-21:[2014-08-21 16:39:34,140][INFO ][node ] [Moonstone] initializing ... logs//elasticsearch.log.2014-08-26:[2014-08-26 12:15:31,948][INFO ][node ] [Hydro-Man] initializing ... logs//elasticsearch.log.2014-08-27:[2014-08-27 11:17:08,325][INFO ][node ] [Joe Fixit] initializing ... logs//elasticsearch.log.2014-08-27:[2014-08-27 23:57:11,077][INFO ][node ] [Overkill] initializing ... APIs # Two built in java clients - port 9300, native protocol\nMust have same Java version\nnode client (non-data mode) transport client (send to remote cluster, does not join the cluster) APIs for Java, JS, Groovy, Perl, PHP, Python, Ruby (even .NET).\nCommunity API for command line\n➜ elasticsearch-1.3.2 curl -s download.elasticsearch.org/es2unix/es \u0026gt;~/bin/es ➜ elasticsearch-1.3.2 es version zsh: permission denied: es ➜ elasticsearch-1.3.2 chmod +x ~/bin/es ➜ elasticsearch-1.3.2 es version es 20140723711d4f9 elasticsearch 1.3.2 ➜ elasticsearch-1.3.2 es indices -v status name pri rep size bytes docs yellow logstash-2014.08.21 5 1 19313 5 yellow shakespeare 5 1 19087632 111396 yellow logstash-2014.08.22 5 1 47220 18 yellow logstash-2014.08.27 5 1 24996521 14490 yellow logstash-2014.08.28 5 1 36012778 22645 yellow kibana-int 5 1 36253 3 yellow .marvel-kibana 5 1 3586 1 yellow logstash-2013.12.11 5 1 9943 1 ➜ elasticsearch-1.3.2 es nodes yI0t6FIPTAm83QlwXWvO1Q 192.168.179.121 9200 192.168.179.121 9300 1.7.0_55 10.6% 0 d * Sea Urchin Restfull API - 9200 # GET, POST, PUT, HEAD, DELETE optional ?pretty Shorthand:\ncurl -XGET \u0026#39;localhost:9200/_count?pretty\u0026#39; -d \u0026#39; { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } }\u0026#39; =\u0026gt;\nGET /_count { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } Documents are in JSON - http://en.wikipedia.org/wiki/Json. All clients handle conversion to JSON automagically\nSee Tutorial on Elastic post\nKibana # Tutorial from: http://www.elasticsearch.org/guide/en/kibana/current/using-kibana-for-the-first-time.html\nApplying mapping to prevent indexing of some fields\ncurl -XPUT http://localhost:9200/shakespeare -d \u0026#39; { \u0026#34;mappings\u0026#34; : { \u0026#34;_default_\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;speaker\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34; : \u0026#34;not_analyzed\u0026#34; }, \u0026#34;play_name\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34; : \u0026#34;not_analyzed\u0026#34; }, \u0026#34;line_id\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;integer\u0026#34; }, \u0026#34;speech_number\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;integer\u0026#34; } } } } } \u0026#39;; {\u0026#34;acknowledged\u0026#34;:true} [2014-08-27 19:43:07,087][INFO ][cluster.metadata ] [Joe Fixit] [shakespeare] creating index, cause [api], shards [5]/[1], mappings [_default_] Loaded shakespeare.json\n","date":"August 27, 2014","externalUrl":null,"permalink":"/posts/2014-08-27-es1/","section":"Posts","summary":"#Installation:\nSee curl -L -O http://download.elasticsearch.org/PATH/TO/VERSION.zip unzip elasticsearch-$VERSION.zip cd elasticsearch-$VERSION Marvel is management plugin - console about cluster. Install:\n./bin/plugin -i elasticsearch/marvel/latest # disable data collection for local cluster echo 'marvel.agent.enabled: false' \u003e\u003e ./config/elasticsearch.yml Test # Startup log:\n➜ elasticsearch-1.3.2 bin/elasticsearch [2014-08-27 11:17:08,325][INFO ][node ] [Joe Fixit] version[1.3.2], pid[59610], build[dee175d/2014-08-13T14:29:30Z] [2014-08-27 11:17:08,325][INFO ][node ] [Joe Fixit] initializing ... [2014-08-27 11:17:08,338][INFO ][plugins ] [Joe Fixit] loaded [marvel], sites [marvel, kopf] [2014-08-27 11:17:10,905][INFO ][marvel.agent ] [Joe Fixit] collecting disabled by settings [2014-08-27 11:17:11,020][INFO ][node ] [Joe Fixit] initialized [2014-08-27 11:17:11,021][INFO ][node ] [Joe Fixit] starting ... [2014-08-27 11:17:11,131][INFO ][transport ] [Joe Fixit] bound_address {inet[/0:0:0:0:0:0:0:0:9300]}, publish_address {inet[/192.168.179.121:9300]} [2014-08-27 11:17:11,148][INFO ][discovery ] [Joe Fixit] elasticsearch/nNgRXlHARHCPutTq7dZXWg [2014-08-27 11:17:14,160][INFO ][cluster.service ] [Joe Fixit] new_master [Joe Fixit][nNgRXlHARHCPutTq7dZXWg][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9300]], reason: zen-disco-join (elected_as_master) [2014-08-27 11:17:14,181][INFO ][http ] [Joe Fixit] bound_address {inet[/0:0:0:0:0:0:0:0:9200]}, publish_address {inet[/192.168.179.121:9200]} [2014-08-27 11:17:14,181][INFO ][node ] [Joe Fixit] started [2014-08-27 11:17:14,726][INFO ][gateway ] [Joe Fixit] recovered [4] indices into cluster_state [2014-08-27 11:18:00,491][INFO ][cluster.service ] [Joe Fixit] added {[logstash-Miros-MacBook-Pro-2.local-59618-4086][Eh5YjUFxSIWIn4xK45xu0w][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9301]]{client=true, data=false},}, reason: zen-disco-receive(join from node[[logstash-Miros-MacBook-Pro-2.local-59618-4086][Eh5YjUFxSIWIn4xK45xu0w][Miros-MacBook-Pro-2.local][inet[/192.168.179.121:9301]]{client=true, data=false}]) Installed some pluggins - marvel, kopf ... ➜ ~ curl 'http://localhost:9200/?pretty' { \"status\" : 200, \"name\" : \"Sea Urchin\", \"version\" : { \"number\" : \"1.3.2\", \"build_hash\" : \"dee175dbe2f254f3f26992f5d7591939aaefd12f\", \"build_timestamp\" : \"2014-08-13T14:29:30Z\", \"build_snapshot\" : false, \"lucene_version\" : \"4.9\" }, \"tagline\" : \"You Know, for Search\" } The sense console allows to avoid using curl and do it from browser: - \u003chttp://localhost:9200/_plugin/marvel/sense/ \u003e\n","title":"Elastic search and Kibana - getting started","type":"post"},{"content":"","date":"August 27, 2014","externalUrl":null,"permalink":"/tags/elasticsearch/","section":"Tags","summary":"","title":"Elasticsearch","type":"tags"},{"content":" Java approach # Use the real time search with this JAR - https://jarscan.com/\n➜ scripts git:(authoring) ✗ java -jar ~/bin/jarscan.jar ========================= JarScan written by Geoff Yaworski gyaworski@hotmail.com Version 2.0 ========================= Usage: java -jar jarscan.jar [-help | /?] [-dir directory name] [-zip] [-showProgress] \u0026lt;-files | -class | -package\u0026gt; \u0026lt;search string 1\u0026gt; [search string 2] [search string n] Help: -help or /? Displays this message. -dir The directory to start searching from default is \u0026#34;.\u0026#34; -zip Also search Zip files -showProgress Show a running count of files read in -files or -class Search for a file or Java class contained in some library. i.e. HttpServlet -package Search for a Java package contained in some library. i.e. javax.servlet.http search string The file or package to search for. i.e. see examples above example\n========================= JarScan written by Geoff Yaworski gyaworski@hotmail.com Version 2.0 ========================= Will start search from: /Users/miro/ATG/ATG11.0/DAS Looking for class(es): [atg.nucleus.NucleusBeanInfo] Processed 196 directories containing 895 files found 115 libraries under the directory: /Users/miro/ATG/ATG11.0/DAS 1) batchconfig.jar [/Users/miro/ATG/ATG11.0/DAS/config/batchconfig.jar] 2) config.jar [/Users/miro/ATG/ATG11.0/DAS/config/config.jar] 3) dtmconfig.jar [/Users/miro/ATG/ATG11.0/DAS/config/dtmconfig.jar] 4) jspbatchconfig.jar [/Users/miro/ATG/ATG11.0/DAS/config/jspbatchconfig.jar] 5) oca-ldap.jar [/Users/miro/ATG/ATG11.0/DAS/config/oca-ldap.jar] 6) config.jar [/Users/miro/ATG/ATG11.0/DAS/configlayers/md5/config.jar] 7) das_ui_help.jar [/Users/miro/ATG/ATG11.0/DAS/help/das_ui_help.jar] 8) ldap.jar [/Users/miro/ATG/ATG11.0/DAS/LDAP/lib/ldap.jar] 9) atg-coherence-classes.jar [/Users/miro/ATG/ATG11.0/DAS/lib/atg-coherence-classes.jar] 10) atg-jaxb-invoker.jar [/Users/miro/ATG/ATG11.0/DAS/lib/atg-jaxb-invoker.jar] 11) axis-1.4.jar [/Users/miro/ATG/ATG11.0/DAS/lib/axis-1.4.jar] 12) bundle-support-standard-1.1.2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/bundle-support-standard-1.1.2.jar] 13) cglib-nodep-2.1_3.jar [/Users/miro/ATG/ATG11.0/DAS/lib/cglib-nodep-2.1_3.jar] 14) classes.jar [/Users/miro/ATG/ATG11.0/DAS/lib/classes.jar] 15) coherence.jar [/Users/miro/ATG/ATG11.0/DAS/lib/coherence.jar] 16) commons-codec-1.3.jar [/Users/miro/ATG/ATG11.0/DAS/lib/commons-codec-1.3.jar] 17) commons-discovery-0.2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/commons-discovery-0.2.jar] 18) commons-logging-1.1.1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/commons-logging-1.1.1.jar] 19) ehcache-core-2.3.2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/ehcache-core-2.3.2.jar] 20) filedist.jar [/Users/miro/ATG/ATG11.0/DAS/lib/filedist.jar] 21) groovy-all-1.7.2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/groovy-all-1.7.2.jar] 22) hibernate-validator-4.3.1.Final.jar [/Users/miro/ATG/ATG11.0/DAS/lib/hibernate-validator-4.3.1.Final.jar] 23) httpclient-4.2.5.jar [/Users/miro/ATG/ATG11.0/DAS/lib/httpclient-4.2.5.jar] 24) httpcore-4.2.4.jar [/Users/miro/ATG/ATG11.0/DAS/lib/httpcore-4.2.4.jar] 25) ice.jar [/Users/miro/ATG/ATG11.0/DAS/lib/ice.jar] 26) jaxb-impl104.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jaxb-impl104.jar] 27) jaxb-libs104.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jaxb-libs104.jar] 28) jboss-logging-3.1.2.GA.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jboss-logging-3.1.2.GA.jar] 29) jline-0.9.94.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jline-0.9.94.jar] 30) jmdns-20.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jmdns-20.jar] 31) joda-time-2.2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/joda-time-2.2.jar] 32) jsp-api.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jsp-api.jar] 33) juel-impl-2.2.5.jar [/Users/miro/ATG/ATG11.0/DAS/lib/juel-impl-2.2.5.jar] 34) jxl-2.6.6.jar [/Users/miro/ATG/ATG11.0/DAS/lib/jxl-2.6.6.jar] 35) min-ejb3-api.jar [/Users/miro/ATG/ATG11.0/DAS/lib/min-ejb3-api.jar] 36) mysql-connector-java-5.1.15-bin.jar [/Users/miro/ATG/ATG11.0/DAS/lib/mysql-connector-java-5.1.15-bin.jar] 37) asn1c.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/asn1c.jar] 38) glassfish.jaxb.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/glassfish.jaxb.jar] 39) javax.persistence.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/javax.persistence.jar] 40) dms.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.dms_11.1.1/dms.jar] 41) fmw_audit.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.iau_11.1.1/fmw_audit.jar] 42) identitystore.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.idm_11.1.1/identitystore.jar] 43) identityutils.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.idm_11.1.1/identityutils.jar] 44) arisId-stack-ovd.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.igf_11.1.1/arisId-stack-ovd.jar] 45) identitydirectory.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.igf_11.1.1/identitydirectory.jar] 46) igf_mbeans.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.igf_11.1.1/igf_mbeans.jar] 47) ojdbc6dms.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jdbc_11.1.1/ojdbc6dms.jar] 48) jacc-spi.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jacc-spi.jar] 49) jps-api.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-api.jar] 50) jps-audit.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-audit.jar] 51) jps-az-api.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-az-api.jar] 52) jps-az-common.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-az-common.jar] 53) jps-az-management.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-az-management.jar] 54) jps-az-rt.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-az-rt.jar] 55) jps-az-sspi.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-az-sspi.jar] 56) jps-common.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-common.jar] 57) jps-ee.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-ee.jar] 58) jps-internal.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-internal.jar] 59) jps-jboss-deployer.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-jboss-deployer.jar] 60) jps-jboss.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-jboss.jar] 61) jps-pep.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-pep.jar] 62) jps-platform.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-platform.jar] 63) jps-se.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-se.jar] 64) jps-tomcat.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-tomcat.jar] 65) jps-unsupported-api.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-unsupported-api.jar] 66) jps-was.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-was.jar] 67) jps-wls-trustprovider.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-wls-trustprovider.jar] 68) jps-wls.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/jps-wls.jar] 69) oracle.security.jps.was.deployment.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.jps_11.1.1/oracle.security.jps.was.deployment.jar] 70) ldapjclnt11.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.ldap_11.1.1/ldapjclnt11.jar] 71) orai18n-service.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.nlsgdk_11.1.0/orai18n-service.jar] 72) ojdl.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.odl_11.1.1/ojdl.jar] 73) osdt_cert.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_cert.jar] 74) osdt_core.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_core.jar] 75) osdt_restsec.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_restsec.jar] 76) osdt_saml.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_saml.jar] 77) osdt_saml2.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_saml2.jar] 78) osdt_ws_sx.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_ws_sx.jar] 79) osdt_wss.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_wss.jar] 80) osdt_xmlsec.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.osdt_11.1.1/osdt_xmlsec.jar] 81) config.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.ovd_11.1.1/config.jar] 82) ovd.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.ovd_11.1.1/ovd.jar] 83) plugins.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.ovd_11.1.1/plugins.jar] 84) oraclepki.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.pki_11.1.1/oraclepki.jar] 85) eclipselink.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.toplink_11.1.1/eclipselink.jar] 86) xmlparserv2_sans_jaxp_services.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/oracle.xdk_11.1.0/xmlparserv2_sans_jaxp_services.jar] 87) org.apache.neethi-2.0.4.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/org.apache.neethi-2.0.4.jar] 88) org.dom4j_1.6.1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/org.dom4j_1.6.1.jar] 89) org.openliberty.arisId_1.1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/org.openliberty.arisId_1.1.jar] 90) org.openliberty.arisIdBeans_1.1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/org.openliberty.arisIdBeans_1.1.jar] 91) org.openliberty.openaz.azapi_1.1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opss/modules/org.openliberty.openaz.azapi_1.1.jar] 92) opssclassloader.jar [/Users/miro/ATG/ATG11.0/DAS/lib/opssclassloader.jar] 93) orawsdl.jar [/Users/miro/ATG/ATG11.0/DAS/lib/orawsdl.jar] 94) protocol.jar [/Users/miro/ATG/ATG11.0/DAS/lib/protocol.jar] 95) resources.jar [/Users/miro/ATG/ATG11.0/DAS/lib/resources.jar] 96) servlet.jar [/Users/miro/ATG/ATG11.0/DAS/lib/servlet.jar] 97) slf4j-api-1.5.11.jar [/Users/miro/ATG/ATG11.0/DAS/lib/slf4j-api-1.5.11.jar] 98) slf4j-jdk14-1.5.11.jar [/Users/miro/ATG/ATG11.0/DAS/lib/slf4j-jdk14-1.5.11.jar] 99) spring-aop-1.2-rc1.jar [/Users/miro/ATG/ATG11.0/DAS/lib/spring-aop-1.2-rc1.jar] 100) subclassloader.jar [/Users/miro/ATG/ATG11.0/DAS/lib/subclassloader.jar] 101) tangosol.jar [/Users/miro/ATG/ATG11.0/DAS/lib/tangosol.jar] 102) validation-api-1.0.0.GA.jar [/Users/miro/ATG/ATG11.0/DAS/lib/validation-api-1.0.0.GA.jar] 103) coreTaglib1_0.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/coreTaglib/1.0/lib/coreTaglib1_0.jar] 104) dspjspTaglib1_0.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/dspjspTaglib/1.0/lib/dspjspTaglib1_0.jar] 105) json-taglib-0.4.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/json/0.4/lib/json-taglib-0.4.jar] 106) jaxen-full.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.0/lib/jaxen-full.jar] 107) jstl.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.0/lib/jstl.jar] 108) saxpath.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.0/lib/saxpath.jar] 109) standard.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.0/lib/standard.jar] 110) jstl.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.1/lib/jstl.jar] 111) standard.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.1/lib/standard.jar] 112) jstl-1.2.jar [/Users/miro/ATG/ATG11.0/DAS/taglib/jstl/1.2/lib/jstl-1.2.jar] 113) config.jar [/Users/miro/ATG/ATG11.0/DAS/Versioned/config/config.jar] 114) config.jar [/Users/miro/ATG/ATG11.0/DAS/Versioned/configlayers/stagingandprod/config.jar] 115) config.jar [/Users/miro/ATG/ATG11.0/DAS/Versioned/liveconfig/config.jar] searching these jarfiles now .... =============================================== Found: atg.nucleus.NucleusBeanInfo Class: atg.nucleus.NucleusBeanInfo Package: atg.nucleus Library Name: classes.jar Library Path: /Users/miro/ATG/ATG11.0/DAS/lib/classes.jar =============================================== Search took: 162 milliseconds. Unix way # real time search - quick and dirty\n#!/bin/bash pattern=$1 shift for jar in $(find $* -type f -name \u0026#34;*.jar\u0026#34;) do # echo Checking: $jar match=`jar -tvf $jar | grep $pattern` if [ ! -z \u0026#34;$match\u0026#34; ] then echo \u0026#34;Found in: $jar\u0026#34; echo \u0026#34;$match\u0026#34; fi done Unix way - preloaded # The following script creates text file with map KEY=value, where KEY is name of the JAR file (relative to root == argument1) and VALUE is the classname.\nExample: # the script run as\n./atgTool.sh $ATG_ROOT/DAS list\nconfig/config.jar=atg.webservice.security.NucleusSecurityManager.properties config/config.jar=atg.webservice.security.NucleusSecurityRepository.properties config/config.jar=atg.webservice.security.RegisteredUsersOnly.properties config/config.jar=atg.webservice.security.nucleusSecurity.xml config/dtmconfig.jar=META-INF.MANIFEST.MF config/dtmconfig.jar=atg.dynamo.transaction.TransactionManager.properties config/jspbatchconfig.jar=META-INF.MANIFEST.MF config/jspbatchconfig.jar=Initial.properties config/jspbatchconfig.jar=Nucleus.properties config/jspbatchconfig.jar=atg.dynamo.service.j2ee.ConnectorContainer.properties config/jspbatchconfig.jar=atg.dynamo.service.j2ee.EJBContainer.properties config/jspbatchconfig.jar=atg.dynamo.service.j2ee.J2EEContainer.properties config/jspbatchconfig.jar=atg.dynamo.service.j2ee.WebContainer.properties config/oca-ldap.jar=META-INF.MANIFEST.MF config/oca-ldap.jar=CONFIG.properties config/oca-ldap.jar=atg.adapter.ldap.InitialContextEnvironment.properties config/oca-ldap.jar=atg.adapter.ldap.InitialContextPool.properties config/oca-ldap.jar=atg.adapter.ldap.LDAPItemCache.properties config/oca-ldap.jar=atg.adapter.ldap.LDAPItemCacheAdapter.properties config/oca-ldap.jar=atg.adapter.ldap.LDAPQueryCache.properties config/oca-ldap.jar=atg.adapter.ldap.LDAPQueryCacheAdapter.properties config/oca-ldap.jar=atg.adapter.ldap.LDAPRepository.properties config/oca-ldap.jar=atg.adapter.ldap.NDSPasswordHasher.properties config/oca-ldap.jar=atg.adapter.ldap.ldapUserProfile.xml configlayers/md5/config.jar=META-INF.MANIFEST.MF configlayers/md5/config.jar=atg.dynamo.security.AdminAccountManager.properties configlayers/md5/config.jar=atg.dynamo.security.AdminUserAuthority.properties configlayers/md5/config.jar=atg.dynamo.security.passwordchecker.AdminPasswordRuleChecker.properties configlayers/md5/config.jar=atg.dynamo.security.passwordchecker.ExpiredPasswordAdminService.properties help/das_ui_help.jar=META-INF.MANIFEST.MF help/das_ui_help.jar=about.html The script: # #!/bin/bash atg=$1 action=$2 usage=\u0026#34;Usage: $0 ATG_ROOT (list|expand)\u0026#34; if [ \u0026#34;x$1\u0026#34; == \u0026#34;x\u0026#34; ] || [ \u0026#34;x$2\u0026#34; == \u0026#34;x\u0026#34; ]; then echo $usage exit 1 fi echo Got ATG=$atg, action=$action # All jars except of archived cache and taglibs which is everywhere alljars=`find $atg -name \u0026#39;*.jar\u0026#39; | grep -v archive-cache | grep -v dspjspTaglib1_0.jar` if [ \u0026#34;$2\u0026#34; == \u0026#34;list\u0026#34; ]; then out_all_classes=`echo $atg | sed \u0026#39;s,/,_,g\u0026#39; | sed \u0026#39;s/^_//\u0026#39;`.txt echo Creating list of classes into:$out_all_classes echo Got `echo $alljars | wc -w` jars for jar in $alljars; do archivename=`echo $jar | sed \u0026#34;s,^$atg/,,g\u0026#34;` echo Processing $jar = $archivename classes=`jar -tf $jar | grep -v \u0026#34;.*/$\u0026#34; | sed \u0026#39;s,/,.,g\u0026#39;` for cls in $classes; do echo $archivename=$cls \u0026gt;\u0026gt;$out_all_classes done done exit 0 fi # list # This will explode all jar archives if [ \u0026#34;$2\u0026#34; == \u0026#34;expand\u0026#34; ]; then out_all_classes_base=`echo $atg | sed \u0026#39;s,/,_,g\u0026#39; | sed \u0026#39;s/^_//\u0026#39;` echo Creating list of classes into:$out_all_classes_base mkdir -p \u0026#34;./$out_all_classes_base\u0026#34; for jar in $alljars; do archivename=`echo $jar | sed \u0026#34;s,^$atg/,,g\u0026#34; | sed \u0026#34;s,/,_,g\u0026#34; | sed \u0026#39;s,\\.,-,g\u0026#39;` echo Processing $jar = $archivename mkdir -p \u0026#34;./$out_all_classes_base/$archivename\u0026#34; unzip $jar -d \u0026#34;./$out_all_classes_base/$archivename\u0026#34; done exit 0 fi echo \u0026#34;Invalid action: $2\u0026#34; echo $usage exit 1 ","date":"August 26, 2014","externalUrl":null,"permalink":"/posts/2014-08-26-find-class/","section":"Posts","summary":"Java approach # Use the real time search with this JAR - https://jarscan.com/\n➜ scripts git:(authoring) ✗ java -jar ~/bin/jarscan.jar ========================= JarScan written by Geoff Yaworski gyaworski@hotmail.com Version 2.0 ========================= Usage: java -jar jarscan.jar [-help | /?] [-dir directory name] [-zip] [-showProgress] \u003c-files | -class | -package\u003e \u003csearch string 1\u003e [search string 2] [search string n] Help: -help or /? Displays this message. -dir The directory to start searching from default is \".\" -zip Also search Zip files -showProgress Show a running count of files read in -files or -class Search for a file or Java class contained in some library. i.e. HttpServlet -package Search for a Java package contained in some library. i.e. javax.servlet.http search string The file or package to search for. i.e. see examples above example\n","title":"Finding out the class in ATG installation","type":"post"},{"content":"As part of \u0026ldquo;back to basics\u0026rdquo; software minimalism movement, I have exported the old Wordpress blog and loaded it into Jekyll with intention to publish it on my Github\nThis contains almost 10 years worth of history of my posts, plus few not yet previously unpublished posts.\nIt is based on Jekyll Clean theme, created by Scott Emmons - see it / get it from github.\nIf you are interested in the Jekyll Clean theme:\nSee the live demo. See it in action on Scott\u0026rsquo;s blog. Migration process # I exported the Wordpress using Admin export tool - which produced the huge XML file.\nI forked the jekyll-clean and made sure it works\n$ git clone git@github.com:miroadamy/jekyll-now.git $ cd jekyll-now $ jekyll build $ jekyll serve $ git remote add upstream git@github.com:scotte/jekyll-clean.git The last one is to allow getting fixes from Scott.\nThen I installed importer and few required gems to run the import\n$ sudo gem install jekyll-paginate $ sudo gem install github-pages $ sudo gem install jekyll-import $ sudo gem install hpricot $ sudo gem install open_uri_redirections $ mv ~/Downloads/miro039sworld.wordpress.2016-03-14.xml .. $ ruby -rubygems -e \u0026#39;require \u0026#34;jekyll-import\u0026#34;; JekyllImport::Importers::WordpressDotCom.run({ \u0026#34;source\u0026#34; =\u0026gt; \u0026#34;/Users/miro/src/PLG/miro039sworld.wordpress.2016-03-14.xml\u0026#34; })\u0026#39; $ git checkout -b master $ git push origin master $ git add . $ git commit -m \u0026#34;Imported the old Wordpress blog from miroadamy.com\u0026#34; Now browse to http://127.0.0.1:4000\nDisqus Comments # I have not set up comments yet as documented here.\nLicense # The content of this theme is distributed and licensed under a Creative Commons Attribution 4.0 License\nThis license lets others distribute, remix, tweak, and build upon your work, even commercially, as long as they credit you for the original creation. This is the most accommodating of licenses offered. Recommended for maximum dissemination and use of licensed materials. In other words: you can do anything you want with this theme on any site, just please provide a link to the original theme on github so I get credit for the original design. Beyond that, have at it!\nThis theme includes the following files which are the properties of their respective owners:\njs/bootstrap.min.js - bootstrap css/bootstrap.min.css - bootstrap js/jquery.min.js - jquery images/cc_by_88x31.png - creative commons css/colorful.css - iwootten/jekyll-syntax ","date":"August 22, 2014","externalUrl":null,"permalink":"/posts/2014-08-22-jekyll-clean-theme/","section":"Posts","summary":"As part of “back to basics” software minimalism movement, I have exported the old Wordpress blog and loaded it into Jekyll with intention to publish it on my Github\nThis contains almost 10 years worth of history of my posts, plus few not yet previously unpublished posts.\nIt is based on Jekyll Clean theme, created by Scott Emmons - see it / get it from github.\nIf you are interested in the Jekyll Clean theme:\n","title":"Third time is a charm","type":"post"},{"content":"Got it working. It is a bit rough around the edges, but functional.\nThe two components\nhttp://localhost:8080/dyn/admin/nucleus/thinkwrap/twatg/script/GroovyDemoScript/ http://localhost:8080/dyn/admin/nucleus/thinkwrap/twatg/script/GroovyScriptRunner/ The are not started via Initial, but that is not a problem.\nThe script tested:\nclass ThatsGroovyDude implements com.thinkwrap.twatg.script.RunnableScript { atg.nucleus.Nucleus nuc = atg.nucleus.Nucleus.getGlobalNucleus(); public String run() { String s = \u0026#34;\u0026#34;; nuc.configPathNames.each { s += \u0026#34;${it}\\n\u0026#34; } return \u0026#34;Hello World!\\n\\n\u0026#34; + s; } } ","date":"May 16, 2014","externalUrl":null,"permalink":"/posts/2014-05-16-atg-groovy-tdd/","section":"Posts","summary":"Got it working. It is a bit rough around the edges, but functional.\nThe two components\nhttp://localhost:8080/dyn/admin/nucleus/thinkwrap/twatg/script/GroovyDemoScript/ http://localhost:8080/dyn/admin/nucleus/thinkwrap/twatg/script/GroovyScriptRunner/ The are not started via Initial, but that is not a problem.\nThe script tested:\nclass ThatsGroovyDude implements com.thinkwrap.twatg.script.RunnableScript { atg.nucleus.Nucleus nuc = atg.nucleus.Nucleus.getGlobalNucleus(); public String run() { String s = \"\"; nuc.configPathNames.each { s += \"${it}\\n\" } return \"Hello World!\\n\\n\" + s; } } ","title":"ATG Groovy TDD","type":"post"},{"content":"","date":"May 16, 2014","externalUrl":null,"permalink":"/tags/tdd/","section":"Tags","summary":"","title":"Tdd","type":"tags"},{"content":"","date":"April 22, 2014","externalUrl":null,"permalink":"/tags/applescript/","section":"Tags","summary":"","title":"Applescript","type":"tags"},{"content":" Move the location of the screenshots # I do not want to have ~/Desktop polluted with files. Thus\nmkdir -p ~/Documents/Screenshots defaults write com.apple.screencapture location ~/Documents/Screenshots killall SystemUIServer Test the screenshot - it does it\nAutomator based auto-rename # Create Folder action for ~/Documents/Screenshots It has 3 actions\ns/Screen Shots // s/./-/g s/ at /_/ ","date":"April 22, 2014","externalUrl":null,"permalink":"/posts/2014-04-22-autorename-screenshots/","section":"Posts","summary":"Move the location of the screenshots # I do not want to have ~/Desktop polluted with files. Thus\nmkdir -p ~/Documents/Screenshots defaults write com.apple.screencapture location ~/Documents/Screenshots killall SystemUIServer Test the screenshot - it does it\nAutomator based auto-rename # Create Folder action for ~/Documents/Screenshots ","title":"Folder action to autorename screenshots","type":"post"},{"content":" How to install Chrome in Centos 6.5 # Step 1. Add Google Yum Repository # Create a new yum repository using below instructions.\nsudo vim /etc/yum.repos.d/google.repo\nAdd following content to this file\n[google] name=Google baseurl=http://dl.google.com/linux/rpm/stable/$basearch enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub Step 2: Install/Update Google Chrome # Richard Lloid provided an shell script to grab libraries from a more recent Linux distro, put them in a tree (/opt/google/chrome/lib) exclusively picked up by Google Chrome and then you can indeed run Google Chrome on CentOS 6.4 or later. Read More\n# wget http://chrome.richardlloyd.org.uk/install_chrome.sh # chmod +x install_chrome.sh # sh install_chrome.sh If you are using older version of Linux distribution, This script will prompt you for confirmation to upgrade system. As per Richard Lloid we need to upgrade system by typing yes to work properly.\nStep 3: Launch Google Chrome # Use following command to start Google Chrome from non root account.\n$ google-chrome or start process in background $ google-chrome \u0026amp; How to Uninstall Google Chrome # If you have used above shell script to install Google chrome. Then you can use use following command to uninstall Google Chrome and its dependencies added by this script.\n# sh install_chrome.sh -u References: http://chrome.richardlloyd.org.uk/\n","date":"April 4, 2014","externalUrl":null,"permalink":"/posts/2014-04-04-install-chrome-centos6/","section":"Posts","summary":"How to install Chrome in Centos 6.5 # Step 1. Add Google Yum Repository # Create a new yum repository using below instructions.\nsudo vim /etc/yum.repos.d/google.repo\nAdd following content to this file\n[google] name=Google baseurl=http://dl.google.com/linux/rpm/stable/$basearch enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub Step 2: Install/Update Google Chrome # Richard Lloid provided an shell script to grab libraries from a more recent Linux distro, put them in a tree (/opt/google/chrome/lib) exclusively picked up by Google Chrome and then you can indeed run Google Chrome on CentOS 6.4 or later. Read More\n","title":"How to install Chrome in Centos 6.5","type":"post"},{"content":"This documents how to enforce the Gitolite permission to make LIVE branch writeable only by team leads\nHow gitolite works # Repository permission structure # This is general format of repo definition\nREPO NAME rule line rule line for example\n@staff = dilbert alice wally bob repo foo RW+ = dilbert # line 1 RW+ dev = alice # line 2 - = wally # line 3 RW temp/ = @staff # line 4 R = ashok # line 5 The Rule line has format:\n\u0026lt;permission\u0026gt; \u0026lt;zero or more refexes\u0026gt; = \u0026lt;one or more users/user groups\u0026gt;\nPermission:\nR - read (clone, fetch) RW - write (push) RW+ - forced write - push that overwrites the server side =\u0026gt; indicates to DENY access REFEX:\nregular expression specifying branch or tag \u0026rsquo; \u0026rsquo; - space is every branch \u0026lsquo;master$\u0026rsquo; - any branch whose name ends on master \u0026lsquo;^LIVE\u0026rsquo; - any branch starting on \u0026lsquo;LIVE\u0026rsquo; \u0026lsquo;^FOO$\u0026rsquo; - branch named exactly \u0026lsquo;foo\u0026rsquo;. the \u0026lsquo;FOO\u0026rsquo; will match, \u0026lsquo;FOOBAR\u0026rsquo; will not \u0026lsquo;FOO\u0026rsquo; - branch that matches \u0026lsquo;FOO\u0026rsquo; both \u0026lsquo;FOO\u0026rsquo; and \u0026lsquo;FOOBAR\u0026rsquo; will match USers or groups:\nnames of users (pub key files) or groups (defined with @- sign) Evaluation of access # Because information may be in multiple files (includes etc), Gitolates accumulates the permissions and creates effective permission FIRST.\nThis is documented in http://gitolite.com/gitolite/rules.html#rule-accum. Here is an example\nThis:\n1 # we have 3 specifically named FOSS projects, but we also consider any 2 # project in the foss/ directory to be FOSS. 3 @FOSS-projects = git gitolite linux foss/..* 4 # similarly for proprietary projects 5 @prop-projects = foo bar baz prop/..* 6 # our users are divided into staff, interns, and bosses 7 @staff = alice dilbert wally 8 @interns = ashok 9 @bosses = PHB 10 # we have certain policies. The first is that FOSS projects are readable 11 # by everyone 12 repo @FOSS-projects 13 R = @all 14 # the second is that bosses can read any repo if they wish to 15 repo @all 16 R = @bosses 17 # now we have specific rules for specific projects 18 repo git 19 RW+ = junio 20 ...some other rules... 21 repo gitolite 22 RW+ = sitaram 23 ...some other rules... 24 ...etc... gets collapsed to this for the \u0026lsquo;gitolite\u0026rsquo; repo\n13 R = @all # since it is a member of @FOSS-projects 16 R = @bosses # since every repo is a member of @all anyway 22 RW+ = sitaram # from the gitolite-specific ruleset 23 ...some other rules... # from the gitolite-specific ruleset This accumulation happens BEFORE any check is done\nPre-git phase (read access) # To check if user has access rights to particular repo, all accumulated rules for that repo and that user are scanned.\nIf Gitolite finds rule with \u0026lsquo;R\u0026rsquo; access, it is permitted. For each rule:\nskip the rule if it does not apply to this user if the rule contains an \u0026ldquo;R\u0026rdquo; (i.e., it is \u0026ldquo;R\u0026rdquo;, \u0026ldquo;RW\u0026rdquo;, or any variant of \u0026ldquo;RW\u0026rdquo;), allow access and stop checking rules If no rule ends with a decision, (\u0026ldquo;fallthru\u0026rdquo;), deny access\nBy default, the DENY rules (one with \u0026lsquo;-\u0026rsquo; are ignored for Read access UNLESS YOU SPECIFY the \u0026lsquo;deny-rule\u0026rsquo; option. Do not do that.\nDetails are at http://gitolite.com/gitolite/rules.html#access-rules\nWrite access # This is what we actually want: make sure that only designated people can push against protected branches.\nWrite access is checked twice, once before passing control to git-receive-pack, and once from within the update hook.\nThe first check is identical to the one for read access, except of course the permission field must contain a \u0026ldquo;W\u0026rdquo;. As before, deny rules are ignored, and you can override that using the deny-rules option. The refex field is also ignored, because at this point we don\u0026rsquo;t know what refs are going to be pushed.\nThe second check happens from within the update hook. Deny rules are considered, which in turn means the sequence of the rules matters.\nHere\u0026rsquo;s how the actual rule matching happens:\ngo through the accumulated rule list for the repo in the sequence they appear in the conf file for each rule: skip the rule if it does not apply to this user If the ref does not match the refex, skip the rule If it\u0026rsquo;s a deny rule, deny access and stop checking rules If the permission field matches the specific type of write operation, allow access and stop checking rules If no rule ends with a decision, (\u0026ldquo;fallthru\u0026rdquo;), deny access Because this is deeply logical, but not necessary intuitive, here are few examples:\n@QA_team = QA_guy QA_gal @Lead_devs = sitaram dilbert @devs = @Lead_devs alice wally repo foo RW refs/tags/v[0-9] = @QA_team RW+ = @Lead_devs RW dev/ = @devs A member of the QA team can only push tags which start with v, followed by a digit (optionally followed by anything else). This allows them to tag repository, but not actually commit new code.\nA lead dev can push or rewind just about anything. (When you don’t supply a pattern between the permissions and the = sign, it means it matches any ref.)\nA normal dev can only push branches whose name starts with dev/.\nAll of these will have read access because deny rules do not work during that phase.\nAn example with deny rules.\nrepo bar RW+ master = @Lead_devs # line 1 - master = @devs # line 2 RW+ = @devs # line 3 This example shows how to protect forced-rewind to anybody but Lead_devs group.\nWhen a normal dev (not a lead dev) tries to rewind-write to “master”, the first matching rule is Line 2, which says “deny”. If a lead dev tries it, though, Line 1 (which comes before Line 2) matches, and allows the access.\nJust as an exercise, think about what happens if you switch Lines 1 and 2. Since “lead” devs are also members of @dev, they will be denied any write access to “master” since the deny rule will be matched first!)\nDevs will have read access to master because the deny rules are ignored during Read check.\nHere is a problematic one:\n# Gitolite permission test repo gitolite-permission-test RW master$ = dev1 lead tester RW LIVE$ = lead R LIVE$ = dev1 tester R vmonly$ = lead RW vmonly$ = dev1 tester Here we want allow only for lead to push against LIVE and only for dev1 and tester against \u0026lsquo;vmonly\u0026rsquo;, while all can push against master.\nThis works OK, HOWEVER - nobody can create any new branch. Let\u0026rsquo;s say lead creates UAT branch. The tests against rules will fail as none of the rules matches UAT.\nCorrect way how to achieve this would be\n# Gitolite permission test repo gitolite-permission-test RW LIVE$ = lead RW vmonly$ = dev1 tester - LIVE$ = dev1 tester - vmonly$ = lead RW = @all Remember - read access is allowed because deny rules are ignored (we have no option set).\nIf lead is trying to push against \u0026lsquo;vmonly\u0026rsquo;, line 5 will stop him. If lead tries to push LIVE, it is allowed by explicit rule #1\nIf dev1 or tester will try to push against vmonly, the rule #2 allows it. If they try to push against LIVE, rule #3 stops them\nIf anybody tries to push against master or any branch other than LIVE or vmonly, the rule #5 will permit proceeding.\nThis is pretty much how we will implement it.\nEnforcing the access rights # The process of enforcement will consist of\ndefining the groups defining the protected branches testing The general pattern is\nrepo gitolite-permission-test RW PROTECTED-BRANCH = @privileged-group - PROTECTED-BRANCH = @read-only-group ... repeat for all branches / groups RW = @all Template for repository rights # Groups # In each Gitolite config, we will define\ndevelopers = all that have read/write access to all non-privileged branches leads = non-rewind access to all branches readonly = read only access (this is Jenkins, Crucible and those without actual push access) admins = full access (rewind) There always\nThe protected branches are (for now)\nLIVE - anything containing LIVE Later on, we may add UAT - some projects may want to run the UAT branches via\nSo the template is\n@admins = miro admin2.name @developers = dev1.name dev2.name @leads = lead1.name lead2.name @readonly = jenkins2 crucible # All repositories sharing same access repo repo1 repo2 RW+ = @admins RW LIVE = @leads - LIVE = @developers RW = @developers R = @readonly There is also automagically defined \u0026lsquo;@all\u0026rsquo; group.\nThis should NOT be used - because it grants access to any uploaded key in keydir/ without having the named user listed in one of the groups above.\nSlowly, we will migrate the existing repos to this structure.\nSources, credits, attributions: # http://gitolite.com/gitolite/rules.html#access-rules http://gitolite.com/gitolite/master-toc.html http://www.opensourceforu.com/2011/01/gitolite-specify-complex-access-controls-git-server/ http://stackoverflow.com/questions/12980750/gitolite-permissions-on-branches http://gitolite.com/gitolite/refex.html http://gitolite.com/gitolite/rules.html#rule-accum http://gitolite.com/gitolite/rules.html#how-are-the-rules-checked ","date":"April 2, 2014","externalUrl":null,"permalink":"/posts/2014-04-02-gitolite-permissions/","section":"Posts","summary":"This documents how to enforce the Gitolite permission to make LIVE branch writeable only by team leads\nHow gitolite works # Repository permission structure # This is general format of repo definition\nREPO NAME rule line rule line for example\n@staff = dilbert alice wally bob repo foo RW+ = dilbert # line 1 RW+ dev = alice # line 2 - = wally # line 3 RW temp/ = @staff # line 4 R = ashok # line 5 The Rule line has format:\n","title":"Gitolite permissions setup","type":"post"},{"content":" Installation of sshfs in the new VM # On Centos 6, the fuse-sshfs is not part of default YUM repos.\nGet the \u0026rsquo;epel\u0026rsquo; repos # wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm sudo rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm Validate\n$ ls -1 /etc/yum.repos.d/epel* /etc/yum.repos.d/remi.repo /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/remi.repo It if good idea to enable the remi by default\nsudo vim /etc/yum.repos.d/remi.repo\nInstallation # sudo yum --enablerepo=epel -y install fuse-sshfs # install from EPEL usermod -a -G fuse thinkwrap Using # Mount the host directory\nsshfs miro@10.0.2.2:/Users/miro/src /home/thinkwrap/MAC ","date":"March 11, 2014","externalUrl":null,"permalink":"/posts/2014-03-11-sshf-in-vm/","section":"Posts","summary":"Installation of sshfs in the new VM # On Centos 6, the fuse-sshfs is not part of default YUM repos.\nGet the ’epel’ repos # wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm sudo rpm -Uvh remi-release-6*.rpm epel-release-6*.rpm Validate\n$ ls -1 /etc/yum.repos.d/epel* /etc/yum.repos.d/remi.repo /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel-testing.repo /etc/yum.repos.d/remi.repo It if good idea to enable the remi by default\n","title":"Installation of sshfs in the new VM","type":"post"},{"content":"I started to see this message in some of my Git environments\nGit 2.0 from \u0026#39;matching\u0026#39; to \u0026#39;simple\u0026#39;. To squelch this message and maintain the current behavior after the default changes, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple This is collection of information gathered from Stackoverflow, Git docs and various internet sources. Putting it together so that I do not have to google it again.\nOptions for push.default # nothing - do not push anything. matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default. upstream - push the current branch to its upstream branch. tracking - deprecated synonym for upstream. current - push the current branch to a branch of the same name. From SOF # See http://stackoverflow.com/questions/11872984/what-is-the-difference-between-git-push-default-current-and-push-default-upstrea\nupstream pushes to the configured upstream branch, current assumes the upstream branch has the same name, and pushes to that specific name. In reality, there\u0026rsquo;s no reason to assume a local branch\u0026rsquo;s upstream tracking branch has the same name as the local branch itself.\nFor example, if you work in multiple repositories or across many shared developer remotes, you often end up tracking different forks of the same branch, such as allen-master or susan-master, both of which track the master branch in Allen and Susan\u0026rsquo;s repos, respectively. In this case, current would be the incorrect setting, because those branch names don\u0026rsquo;t exist on their remotes. upstream, however, would work just fine.\nA more practical example might be tracking both a development and production repository. Your workflow might use a different mainline branch for each, but that might get confusing. Suppose you were a code integrator and wanted to track both repositories\u0026rsquo; master branches separately.\ngit checkout -b production --track production/master git checkout -b development --track development/master Now you\u0026rsquo;ve got two branches that track their respective repositories, neither of which use the masternaming convention at all. There\u0026rsquo;s little confusion about the branch names: They explicitly describe what they track. Nevertheless, push.default = current wouldn\u0026rsquo;t make any sense as neither remote contains a development or production branch.\nsimple as push.default # Value of push.default defines the action git push should take if no refspec is explicitly given.\nDifferent values are well-suited for specific workflows. In a purely central workflow (i.e. the fetch source is equal to the push destination), upstream is probably what you want.\nPossible values are:\nnothing # do not push anything (error out) unless a refspec is explicitly given. This is primarily meant for people who want to avoid mistakes by always being explicit.\ncurrent # push the current branch to update a branch with the same name on the receiving end. Works in both central and non-central workflows.\nupstream # push the current branch back to the branch whose changes are usually integrated into the current branch (which is called @{upstream}). This mode only makes sense if you are pushing to the same repository you would normally pull from (i.e. central workflow).\nsimple # in centralized workflow, work like upstream with an added safety to refuse to push if the upstream branch\u0026rsquo;s name is different from the local one. When pushing to a remote that is different from the remote you normally pull from, work as current. This is the safest option and is suited for beginners. This mode will become the default in Git 2.0.\nmatching # push all branches having the same name on both ends. This makes the repository you are pushing to remember the set of branches that will be pushed out (e.g. if you always push maint and master there and no other branches, the repository you push to will have these two branches, and your local maint and master will be pushed there).\nTo use this mode effectively, you have to make sure all the branches you would push out are ready to be pushed out before running git push, as the whole point of this mode is to allow you to push all of the branches in one go. If you usually finish work on only one branch and push out the result, while other branches are unfinished, this mode is not for you. Also this mode is not suitable for pushing into a shared central repository, as other people may add new branches there, or update the tip of existing branches outside your control.\nThis is currently the default, but Git 2.0 will change the default to simple.\nNote to self # Changed the default to simple.\n","date":"December 31, 2013","externalUrl":null,"permalink":"/posts/2013-12-31-difference-between-matching-and-simple-git-push/","section":"Posts","summary":"I started to see this message in some of my Git environments\nGit 2.0 from 'matching' to 'simple'. To squelch this message and maintain the current behavior after the default changes, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple This is collection of information gathered from Stackoverflow, Git docs and various internet sources. Putting it together so that I do not have to google it again.\n","title":"Difference between matching and simple Git push","type":"post"},{"content":"If you use DashDoc (see http://kapeli.com/dash), it can be integrated with editor or Eclipse to allow automatically find selected text in Dash documentation sets:\nSublime Text # This is easy - there is DashDoc plugin - https://sublime.wbond.net/packages/DashDoc\nThe plugin is OS-X specific, because the DashDoc is\nStart Package Control (Cmd-Shift-P) select Install Package (type Install) select DashDoc The Ctrl-H does the search\nEclipse # There is opensource plugin for it at https://github.com/justinkb/DashLookup#readme.\nclone the repo - https://github.com/justinkb/DashLookup#readme Open Eclipse and Import project to Workspace Build it Select \u0026lsquo;Export deployable plugin and Fragments\u0026rsquo; and install to host: Bind the command DashLookup (Preferences -\u0026gt; General -\u0026gt; Keys) to keys of your choice\nVim # See https://github.com/rizzatti/dash.vim#readme\nI am using Pathogen, so\ncd ~/.vim/bundle git clone https://github.com/rizzatti/funcoo.vim.git git clone https://github.com/rizzatti/dash.vim.git The submodule file needs to be edited with these locations:\n.vim $ cat .gitmodules | pbcopy [submodule \u0026#34;bundle/vim-fugitive\u0026#34;] path = bundle/vim-fugitive url = git://github.com/tpope/vim-fugitive.git ignore = untracked [submodule \u0026#34;bundle/vim-pathogen\u0026#34;] path = bundle/vim-pathogen url = git://github.com/tpope/vim-pathogen.git ignore = untracked [submodule \u0026#34;bundle/tlib_vim\u0026#34;] path = bundle/tlib_vim url = git://github.com/tomtom/tlib_vim.git ignore = untracked [submodule \u0026#34;bundle/vim-unimpaired\u0026#34;] path = bundle/vim-unimpaired url = git://github.com/tpope/vim-unimpaired.git ignore = untracked [submodule \u0026#34;bundle/funcoo.vim\u0026#34;] path = bundle/funcoo.vim url = https://github.com/rizzatti/funcoo.vim.git ignore = untracked [submodule \u0026#34;bundle/dash.vim\u0026#34;] path = bundle/dash.vim url = https://github.com/rizzatti/dash.vim.git ignore = untracked The new command is :Dash and the mapping to search word under cursor is\n:nmap \u0026lt;silent\u0026gt; \u0026lt;leader\u0026gt;d \u0026lt;Plug\u0026gt;DashSearch :nmap \u0026lt;silent\u0026gt; \u0026lt;leader\u0026gt;D \u0026lt;Plug\u0026gt;DashGlobalSearch The leader is \u0026lsquo;'\n","date":"December 31, 2013","externalUrl":null,"permalink":"/posts/2013-12-31-binding-dashdoc-with-editors-and-eclipse/","section":"Posts","summary":"If you use DashDoc (see http://kapeli.com/dash), it can be integrated with editor or Eclipse to allow automatically find selected text in Dash documentation sets:\nSublime Text # This is easy - there is DashDoc plugin - https://sublime.wbond.net/packages/DashDoc\nThe plugin is OS-X specific, because the DashDoc is\nStart Package Control (Cmd-Shift-P) select Install Package (type Install) select DashDoc The Ctrl-H does the search\n","title":"Binding DashDoc with editors and Eclipse","type":"post"},{"content":"","date":"December 31, 2013","externalUrl":null,"permalink":"/tags/vim/","section":"Tags","summary":"","title":"Vim","type":"tags"},{"content":"The continuation of the old Wordpress blog with more agreeable tools: Github Wiki + Gollum, Markdown and Git.\nMy old blog at Miro\u0026rsquo;s World has been kinda neglected in last two years. I have written several entries and published them only internally. I have decided now to pull those of the entries that do not contain customer references, code or customer IP out.\n","date":"December 31, 2013","externalUrl":null,"permalink":"/posts/2013-12-31-httpsgithub-comradegastmiroadamy-dot-comwiki/","section":"Posts","summary":"The continuation of the old Wordpress blog with more agreeable tools: Github Wiki + Gollum, Markdown and Git.\nMy old blog at Miro’s World has been kinda neglected in last two years. I have written several entries and published them only internally. I have decided now to pull those of the entries that do not contain customer references, code or customer IP out.\n","title":"Miro's World 2.0","type":"post"},{"content":"","date":"October 16, 2013","externalUrl":null,"permalink":"/tags/endeca/","section":"Tags","summary":"","title":"Endeca","type":"tags"},{"content":"I have ported the Oracle VM style management scripts into the Loyalty VM.\nThe scripts are in the loyalty-endeca Git repo, originally in eVoucher branch but also merged into edc\n[tkuser@vm-lo1-hpr-ma endeca]$ ls -1 total 28 dev-check-environment.sh* dev-deploy-endeca-app.sh* dev-endeca-environmet.ini* dev-remove-endeca-app.sh* endeca-control* endeca-vars.txt* README.md* RewardsEndc/ dev-endeca-environmet.ini # This is environment setting script.\n### MUST BE SOURCED IN source dev-endeca-environmet.ini ## or . dev-endeca-environmet.ini ## NEVER ./dev-endeca-environmet.ini endeca-control # Main script that manages three components of the system named:\nplatform em (the Workbench actually, but em is shorter) cas all - all three of them Assumes the environment initialized by dev-endeca-environment.ini\nExpects 2 arguments\nendeca-control INSTANCE ACTION where INSTANCE is one of (platform, em, cas, all) and ACTION is one of (start, stop, restart, kill)\nExample # [tkuser@vm-lo1-hpr-ma endeca]$ ./endeca-control all start STARTING PLATFORM ---- STARTING EXPERIENCE MANAGER ---- STARTING CAS ---- [tkuser@vm-lo1-hpr-ma endeca]$ ./endeca-control all kill SHUTTING DOWN PLATFORM ---- Using ENDECA_ROOT: /home/tkuser/endeca/PlatformServices/6.1.3 Using ENDECA_CONF: /home/tkuser/endeca/PlatformServices/workspace Using CATALINA_BASE: /home/tkuser/endeca/PlatformServices/workspace Using CATALINA_HOME: /home/tkuser/endeca/PlatformServices/6.1.3/tools/server Using CATALINA_TMPDIR: /home/tkuser/endeca/PlatformServices/workspace/temp Using JRE_HOME: /home/tkuser/endeca/PlatformServices/6.1.3/j2sdk Using CLASSPATH: /home/tkuser/endeca/PlatformServices/6.1.3/tools/server/bin/bootstrap.jar SHUTTING DOWN EXPERIENCE MANAGER ---- Checking Workbench Environment Settings Using ENDECA_TOOLS_ROOT: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2 Using ENDECA_TOOLS_CONF: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace Using LOGGING_DIR: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace/logs Using CATALINA_HOME: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/apache-tomcat-6.0.32 Using CATALINA_BASE: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace Using JAVA_HOME: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/j2sdk Using JRE_HOME: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/j2sdk Using WORKING_DIR: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace/state Using CATALINA_OPTS: -Xms256m -Xmx1024m -XX:MaxPermSize=512m -Dcom.endeca.manager.endecaroot=/home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace Using JAVA_OPTS: -Djava.security.auth.login.config=/home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace/conf/Login.conf -Dorg.apache.catalina.SESSION_COOKIE_NAME=ESESSIONID -Dorg.apache.catalina.SESSION_PARAMETER_NAME=esessionid -XX:CompileCommand=exclude,org/apache/derby/impl/services/locks/LockControl,getLock -XX:CompileCommand=exclude,org/apache/derby/impl/services/locks/LockControl,addLock -XX:CompileCommand=exclude,org/apache/derby/impl/services/locks/LockControl,isGrantable -XX:+UnlockDiagnosticVMOptions -XX:-DisplayVMOutput Stopping Workbench Using CATALINA_BASE: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace Using CATALINA_HOME: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/apache-tomcat-6.0.32 Using CATALINA_TMPDIR: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/workspace/temp Using JRE_HOME: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/j2sdk Using CLASSPATH: /home/tkuser/endeca/ToolsAndFrameworks/3.1.2/server/apache-tomcat-6.0.32/bin/bootstrap.jar SHUTTING DOWN CAS ---- [tkuser@vm-lo1-hpr-ma endeca]$ ","date":"October 16, 2013","externalUrl":null,"permalink":"/posts/2013-10-16-endeca-oracle/","section":"Posts","summary":"I have ported the Oracle VM style management scripts into the Loyalty VM.\nThe scripts are in the loyalty-endeca Git repo, originally in eVoucher branch but also merged into edc\n[tkuser@vm-lo1-hpr-ma endeca]$ ls -1 total 28 dev-check-environment.sh* dev-deploy-endeca-app.sh* dev-endeca-environmet.ini* dev-remove-endeca-app.sh* endeca-control* endeca-vars.txt* README.md* RewardsEndc/ dev-endeca-environmet.ini # This is environment setting script.\n### MUST BE SOURCED IN source dev-endeca-environmet.ini ## or . dev-endeca-environmet.ini ## NEVER ./dev-endeca-environmet.ini endeca-control # Main script that manages three components of the system named:\n","title":"Endeca start scripts - Oracle way","type":"post"},{"content":"","date":"October 16, 2013","externalUrl":null,"permalink":"/tags/oracle/","section":"Tags","summary":"","title":"Oracle","type":"tags"},{"content":"Git message\nGit 2.0 from \u0026#39;matching\u0026#39; to \u0026#39;simple\u0026#39;. To squelch this message and maintain the current behavior after the default changes, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple Options for push.default\nnothing - do not push anything. matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default. upstream - push the current branch to its upstream branch. tracking - deprecated synonym for upstream. current - push the current branch to a branch of the same name. From SOF:\nupstream pushes to the configured upstream branch, current assumes the upstream branch has the same name, and pushes to that specific name. In reality, there\u0026rsquo;s no reason to assume a local branch\u0026rsquo;s upstream tracking branch has the same name as the local branch itself.\nFor example, if you work in multiple repositories or across many shared developer remotes, you often end up tracking different forks of the same branch, such as allen-master or susan-master, both of which track the master branch in Allen and Susan\u0026rsquo;s repos, respectively. In this case, current would be the incorrect setting, because those branch names don\u0026rsquo;t exist on their remotes. upstream, however, would work just fine.\nA more practical example might be tracking both a development and production repository. Your workflow might use a different mainline branch for each, but that might get confusing. Suppose you were a code integrator and wanted to track both repositories\u0026rsquo; master branches separately.\ngit checkout -b production --track production/master git checkout -b development --track development/master Now you\u0026rsquo;ve got two branches that track their respective repositories, neither of which use the masternaming convention at all. There\u0026rsquo;s little confusion about the branch names: They explicitly describe what they track. Nevertheless, push.default = current wouldn\u0026rsquo;t make any sense as neither remote contains a development or production branch.\nSimple # push.default # Defines the action git push should take if no refspec is explicitly given. Different values are well-suited for specific workflows; for instance, in a purely central workflow (i.e. the fetch source is equal to the push destination), upstream is probably what you want. Possible values are:\nnothing - do not push anything (error out) unless a refspec is explicitly given. This is primarily meant for people who want to avoid mistakes by always being explicit. current - push the current branch to update a branch with the same name on the receiving end. Works in both central and non-central workflows. upstream - push the current branch back to the branch whose changes are usually integrated into the current branch (which is called @{upstream}). This mode only makes sense if you are pushing to the same repository you would normally pull from (i.e. central workflow). simple - in centralized workflow, work like upstream with an added safety to refuse to push if the upstream branch\u0026rsquo;s name is different from the local one. When pushing to a remote that is different from the remote you normally pull from, work as current. This is the safest option and is suited for beginners.\nThis mode will become the default in Git 2.0.\nmatching - push all branches having the same name on both ends. This makes the repository you are pushing to remember the set of branches that will be pushed out (e.g. if you always push maint and master there and no other branches, the repository you push to will have these two branches, and your local maint and master will be pushed there).\nTo use this mode effectively, you have to make sure all the branches you would push out are ready to be pushed out before running git push, as the whole point of this mode is to allow you to push all of the branches in one go. If you usually finish work on only one branch and push out the result, while other branches are unfinished, this mode is not for you. Also this mode is not suitable for pushing into a shared central repository, as other people may add new branches there, or update the tip of existing branches outside your control.\nThis is currently the default, but Git 2.0 will change the default to simple.\nChanged the default to simple.\n","date":"September 26, 2013","externalUrl":null,"permalink":"/posts/2013-09-26-git-push-matching-simple/","section":"Posts","summary":"Git message\nGit 2.0 from 'matching' to 'simple'. To squelch this message and maintain the current behavior after the default changes, use: git config --global push.default matching To squelch this message and adopt the new behavior now, use: git config --global push.default simple Options for push.default\nnothing - do not push anything. matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default. upstream - push the current branch to its upstream branch. tracking - deprecated synonym for upstream. current - push the current branch to a branch of the same name. From SOF:\n","title":"Difference between matching and simple - Git push","type":"post"},{"content":"","date":"September 25, 2013","externalUrl":null,"permalink":"/tags/editors/","section":"Tags","summary":"","title":"Editors","type":"tags"},{"content":" Sublime text macro to insert timestamp # platform-edc $ cat ~/Library/Application\\ Support/Sublime\\ Text\\ 2/Packages/User/time_stamp.py import sublime_plugin from datetime import datetime class TimeStampCommand(sublime_plugin.TextCommand): def run(self, edit): # formatting options at http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior stamp = datetime.now().strftime(\u0026#34;%Y-%m-%d_%H:%M:%S\u0026#34;) # 2013-07-18 14:54:23 for r in self.view.sel(): if r.empty(): self.view.insert(edit, r.a, stamp) else: self.view.replace(edit, r, stamp) platform-edc $ Documentation - see\nInstallation: # Add this to Keybindings / User\n![](/images/2013-09-23_8.02.19 PM.png)\n","date":"September 25, 2013","externalUrl":null,"permalink":"/posts/2013-09-25-sublime-text-macro-timestamp/","section":"Posts","summary":"Sublime text macro to insert timestamp # platform-edc $ cat ~/Library/Application\\ Support/Sublime\\ Text\\ 2/Packages/User/time_stamp.py import sublime_plugin from datetime import datetime class TimeStampCommand(sublime_plugin.TextCommand): def run(self, edit): # formatting options at http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior stamp = datetime.now().strftime(\"%Y-%m-%d_%H:%M:%S\") # 2013-07-18 14:54:23 for r in self.view.sel(): if r.empty(): self.view.insert(edit, r.a, stamp) else: self.view.replace(edit, r, stamp) platform-edc $ Documentation - see\n","title":"Sublime text macro to insert timestamp","type":"post"},{"content":" How to make screenshot from command line # platform-edc $ screencapture -i ~/Desktop/$(date +%Y%m%d%H%M%S).png libpng warning: zero length keyword libpng warning: Empty language field in iTXt chunk platform-edc $ screencapture ~/Desktop/A$(date +%Y%m%d%H%M%S).png libpng warning: zero length keyword libpng warning: Empty language field in iTXt chunk First one is \u0026ldquo;interactive\u0026rdquo; - Cmd-Shift-3 with selection tool, second is full screen\n","date":"September 24, 2013","externalUrl":null,"permalink":"/posts/2013-09-24-screenshot-cli/","section":"Posts","summary":"How to make screenshot from command line # platform-edc $ screencapture -i ~/Desktop/$(date +%Y%m%d%H%M%S).png libpng warning: zero length keyword libpng warning: Empty language field in iTXt chunk platform-edc $ screencapture ~/Desktop/A$(date +%Y%m%d%H%M%S).png libpng warning: zero length keyword libpng warning: Empty language field in iTXt chunk First one is “interactive” - Cmd-Shift-3 with selection tool, second is full screen\n","title":"How to make screenshot from command line","type":"post"},{"content":" Case sensitivity and VirtualBox shared folder # Weird but true behaviour:\nI have the case sensitive encrypted disk (sparse bundle with HFSX type) mounted in VBox shared folders. All works fine, after VM starts:\ntouch zz zZ creates two files, both \u0026ldquo;inside VM\u0026rdquo; ~/development/ATG/platform-edc as well as in OS-X.\nIf the VM is suspended and resumed, it looses the case sensitivity inside the VM.\nThe command\ncd ~/development/ATG/platform-edc touch zz zZ will create just single file. Outside the VM, in OS-X file system is still case sensitive.\nIt looks as if the wake-up remounted the volumen and normal HFS+ instead of HFSX\n","date":"September 16, 2013","externalUrl":null,"permalink":"/posts/2013-09-16-vbox-shared-folder/","section":"Posts","summary":"Case sensitivity and VirtualBox shared folder # Weird but true behaviour:\nI have the case sensitive encrypted disk (sparse bundle with HFSX type) mounted in VBox shared folders. All works fine, after VM starts:\ntouch zz zZ creates two files, both “inside VM” ~/development/ATG/platform-edc as well as in OS-X.\nIf the VM is suspended and resumed, it looses the case sensitivity inside the VM.\n","title":"Case sensitivity and VirtualBox shared folder","type":"post"},{"content":" Usable mc color scheme # Edit\n~/.mc/ini\ninsert\n[Colors] base_color=lightgray,blue:normal=blue,default:selected=white,brightblue:marked=yellow,default:markselect=yellow,gray:directory=brightblue,default:executable=brightgreen,default:link=cyan,default:device=brightmagenta,default:special=lightgray,default:errors=red,default:reverse=green,default:gauge=green,default:input=white,gray:dnormal=green,gray:dfocus=brightgreen,gray:dhotnormal=cyan,gray:dhotfocus=brightcyan,gray:menu=green,default:menuhot=cyan,default:menusel=green,gray:menuhotsel=cyan,default:helpnormal=cyan,default:editnormal=green,default:editbold=blue,default:editmarked=gray,blue:stalelink=red,default ","date":"September 5, 2013","externalUrl":null,"permalink":"/posts/2013-09-05-mc-color-scheme/","section":"Posts","summary":"Usable mc color scheme # Edit\n~/.mc/ini\ninsert\n[Colors] base_color=lightgray,blue:normal=blue,default:selected=white,brightblue:marked=yellow,default:markselect=yellow,gray:directory=brightblue,default:executable=brightgreen,default:link=cyan,default:device=brightmagenta,default:special=lightgray,default:errors=red,default:reverse=green,default:gauge=green,default:input=white,gray:dnormal=green,gray:dfocus=brightgreen,gray:dhotnormal=cyan,gray:dhotfocus=brightcyan,gray:menu=green,default:menuhot=cyan,default:menusel=green,gray:menuhotsel=cyan,default:helpnormal=cyan,default:editnormal=green,default:editbold=blue,default:editmarked=gray,blue:stalelink=red,default ","title":"Usable mc color scheme","type":"post"},{"content":" Show lock screen indicator in OS-X menu # After HDD reinstall I lost most of my customizations (by choice decided NOT to restore from TM).\nThe Lock in menu is provided by KeyChain Access, not by System Preferences.\nOpen \u0026lsquo;KeyChain Access\u0026rsquo; -\u0026gt; Preferences, select \u0026lsquo;Show keychain status\u0026rsquo;\nand it is back:\n","date":"September 3, 2013","externalUrl":null,"permalink":"/posts/2013-09-03-show-lock-screen-indicator/","section":"Posts","summary":"Show lock screen indicator in OS-X menu # After HDD reinstall I lost most of my customizations (by choice decided NOT to restore from TM).\nThe Lock in menu is provided by KeyChain Access, not by System Preferences.\nOpen ‘KeyChain Access’ -\u003e Preferences, select ‘Show keychain status’\nand it is back:\n","title":"Show lock screen indicator in OS-X menu","type":"post"},{"content":"Brief description of my latest setup I use for CPL and LCH - in case I forget it or somebody wants to replicate it.\nInspiration for the setup came from https://www.youtube.com/watch?feature=player_embedded\u0026v=cPt_1Vga-Nk\nMotivation - issues with VMs # VMs are great - they allow \u0026ldquo;packaged\u0026rdquo; dev environment and quick start for the new member of the team. Start a VM on local or remote host, connect with VNC or Remote Desktop and you are in business.\nFor longer running projects, it is still suboptimal environment compared to \u0026ldquo;native\u0026rdquo; environments. Here is my list of issues with developing inside VM (running Eclipse, browsers and all tools in addition of ATG)\nUI comfort. Linux, especially the older Centos 4 and Centos 5 are nowhere close to UI comfort of OS-X, or even Windows 7 for that matter old tools, old libraries: because of the older versions of clib, gclib, it is a problem to install recent versions of browsers (Chrome, FF), recent editors missing tools: some tools (like SourceTree, Curio) do not exist for Linux at all speed: you may have quacore notebook, but effective user responsiveness will be same as single core old PC 4 years back because everything competes for single CPU cycles: DB, ATG, Eclipse RAM: to run 2 instance of ATG with memory hungry Eclipse requires beefed up VM memory settings and that will slow down front end VPN: it is hard to access VPN from Linux. Using VNC remote desktop via VPN (when VM runs inside office) is an exercise in patience \u0026hellip;) Setup # I am using VM running primarily out of my notebook - on MacMini or on Chewbaca, but it can be used with local VM as well.\nVM must be Linux based (to allow simple access via ssh) and does not need to run any UI after you configure it. VM must run Samba and export the home directory as writeable.\nAll my VMs are using layout with ATG installed in ~/opt/ATG and JBoss in ~/opt/jboss-something, with installed Oracle XE and samba out of the box.\nIf samba is not install, add it: sudo yum install samba\nSamba configuration # Simplest way is to use Administration Menu in Linux UI\nSet up Samba user as tkuser / $PWD\nAfter this you can logout and kill VNC.\nMac side setup # Map the Samba drive:\nuse either mount_smbsf or GUI in PathFinder / Finder. The mapped drive will look like this: create new Workspace in Eclipse referring the files on the /Volumes/tkuser/opt/ATG/ATG10.0.3/ClientName connect multiple SSH sessions to remote hosts that allow to run ant, start ATG, do Git operations and such create local terminal session to /Volumes/tkuser/opt/... to run Mac tools over source - Sublime Text, etc Hints and tricks # These are little things that make is more convenient:\nMap the symbolic name of the VM in /etc/hosts\nI am using convention CLIENT-VM-partialIP\nUse color coding in terminal (iTerm specific)\nTo tell which terminal is \u0026ldquo;local\u0026rdquo;, I color them - the brownish ones are remotes, green is local\nAlways create local workspace in Eclipse\nUsing the setup and limitations # This setup can be used from Mac or Windows development station, with local or remote back-end VM. If you are on mac, you have everything. On Windows, you need install decent ssh client and terminal - both of which comes with Git Extensions\nIf you are on Windows, you need to use different \u0026ldquo;shell\u0026rdquo; for local terminal sessions and remote terminal sessions (if the command interpreter of Windows can be named \u0026ldquo;shell\u0026rdquo; \u0026hellip;)\nIn theory the VM could be Windows based - but instead of accessing it using ssh, you would have to start remote desktop client and open the command windows there \u0026hellip; and suffer with their limitations. You could not get rid of UI, but at least you could run Eclipse on local hardware without double-slowdown caused by VMWare and Windows.\nLinux -\u0026gt; Linux # This is very feasible alternative that allows to use older version of Linux kernel to run the ATG and modern Ubuntu with all the bells and whistles for running Eclipse. It also removes a need for customizing and reconfiguring/updating multiple versions of Eclipse for multiple VMs.\n","date":"April 22, 2013","externalUrl":null,"permalink":"/posts/2013-04-22-atg-development/","section":"Posts","summary":"Brief description of my latest setup I use for CPL and LCH - in case I forget it or somebody wants to replicate it.\nInspiration for the setup came from https://www.youtube.com/watch?feature=player_embedded\u0026v=cPt_1Vga-Nk\nMotivation - issues with VMs # VMs are great - they allow “packaged” dev environment and quick start for the new member of the team. Start a VM on local or remote host, connect with VNC or Remote Desktop and you are in business.\n","title":"ATG Development using 'hidden' VM","type":"post"},{"content":"I was merging the branch that removed / consolidated bunch of duplicate JSP files (corporate-ui-cleanup).\nIn the meantime in master, some minor UI changes were made to these files whose content was now elsewhere.\nQuick trick how to resolve it fast:\nShow branch # CineplexB2B $ git show-branch ! [bb-database-cleanup] Loading data with XML only: no constraints and tax_id (unused field) nullable ! [bb-gradle-build] Merge branch \u0026#39;master\u0026#39; into bb-gradle-build * [bb-master] Merged in the last 5 days changes ! [corporate-ui-cleanup] Merged in the last 5 days changes ! [master] Merged in the last 5 days changes ----- - [bb-gradle-build] Merge branch \u0026#39;master\u0026#39; into bb-gradle-build ---- [bb-master] Merged in the last 5 days changes +*++ [bb-master^2] CPLXB2B-562, usageInfo/internalUsageInfo mapping in CFI +*++ [bb-master^2^] return order goes all the way to NEW: replaced SetPaymentGroupAmount, added ReturnFee calculator, added reusable jsp fragments for sales order pages +*++ [bb-master^2~2] Styling change to avoid disappearing links inside Terms and Conditions +*++ [bb-master^2~3] Dealing with consequences if INTERNAL split to INTERNAL_TRANSFER and INTERNAL_PURCHASE ---- [bb-master^2~4] Merge remote-tracking branch \u0026#39;origin/master\u0026#39; into uat2-deploy ---- [bb-master^2~4^2] Merge branch \u0026#39;master\u0026#39; of luke:cineplex-b2b +*++ [bb-master^2~4^2^] merged changes - fixed conflict +*++ [bb-master^2~4^2~2] CPLXBTOB-557 - fixed amount column to show proper currency ---- [bb-master^2~4^2~3] Merge branch \u0026#39;master\u0026#39; of twgit@luke:cineplex-b2b.git +*++ [bb-master^2~4^2~4] CPLXBTOB-484 - fixed the spacing and comma issues +*++ [bb-master^2~5] Reverted 4d512ed - issue with recalculate. Must be solved selectively via Javascript +*++ [bb-master^2~6] Spacing in header see also version with --current\nCineplexB2B $ git show-branch --current master ! [master] Merged in the last 5 days changes * [bb-master] Merged in the last 5 days changes -- -- [master] Merged in the last 5 days changes For more, see http://stackoverflow.com/questions/2255416/how-to-determine-when-a-git-branch-was-created\nFind difference # between 2 versions of the file which existed on master - since 13 commits ago\ngit diff master~13:cineplex/j2ee-apps/cineplex.ear/b2b.war/profile/gadgets/applicationReview_content.jsp master:cineplex/j2ee-apps/cineplex.ear/b2b.war/profile/gadgets/applicationReview_content.jsp Save the diff to file open the new location find \u0026ldquo;shared\u0026rdquo; part from the diff paste changed parts To resolve the merge, one must remove the file and add the change in new file\n","date":"April 13, 2013","externalUrl":null,"permalink":"/posts/2013-04-13-git-conflict/","section":"Posts","summary":"I was merging the branch that removed / consolidated bunch of duplicate JSP files (corporate-ui-cleanup).\nIn the meantime in master, some minor UI changes were made to these files whose content was now elsewhere.\nQuick trick how to resolve it fast:\nShow branch # CineplexB2B $ git show-branch ! [bb-database-cleanup] Loading data with XML only: no constraints and tax_id (unused field) nullable ! [bb-gradle-build] Merge branch 'master' into bb-gradle-build * [bb-master] Merged in the last 5 days changes ! [corporate-ui-cleanup] Merged in the last 5 days changes ! [master] Merged in the last 5 days changes ----- - [bb-gradle-build] Merge branch 'master' into bb-gradle-build ---- [bb-master] Merged in the last 5 days changes +*++ [bb-master^2] CPLXB2B-562, usageInfo/internalUsageInfo mapping in CFI +*++ [bb-master^2^] return order goes all the way to NEW: replaced SetPaymentGroupAmount, added ReturnFee calculator, added reusable jsp fragments for sales order pages +*++ [bb-master^2~2] Styling change to avoid disappearing links inside Terms and Conditions +*++ [bb-master^2~3] Dealing with consequences if INTERNAL split to INTERNAL_TRANSFER and INTERNAL_PURCHASE ---- [bb-master^2~4] Merge remote-tracking branch 'origin/master' into uat2-deploy ---- [bb-master^2~4^2] Merge branch 'master' of luke:cineplex-b2b +*++ [bb-master^2~4^2^] merged changes - fixed conflict +*++ [bb-master^2~4^2~2] CPLXBTOB-557 - fixed amount column to show proper currency ---- [bb-master^2~4^2~3] Merge branch 'master' of twgit@luke:cineplex-b2b.git +*++ [bb-master^2~4^2~4] CPLXBTOB-484 - fixed the spacing and comma issues +*++ [bb-master^2~5] Reverted 4d512ed - issue with recalculate. Must be solved selectively via Javascript +*++ [bb-master^2~6] Spacing in header see also version with --current\n","title":"Merge conflict with deleted file","type":"post"},{"content":"# Test if it is sourced or not if [[ $0 != .*bash ]]; then echo Please source it: . $0 exit 1 fi res=`gradle --version \u0026gt;/dev/null 2\u0026gt;\u0026amp;1; echo $? ` if [[ $res == \u0026#34;0\u0026#34; ]]; then echo Have gradle: `which gradle` gradle --version else export GRADLE_HOME=~/opt/gradle export PATH=$PATH:$GRADLE_HOME/bin echo No Gradle, adding - `which gradle` gradle --version fi ","date":"April 9, 2013","externalUrl":null,"permalink":"/posts/2013-04-09-bash/","section":"Posts","summary":"# Test if it is sourced or not if [[ $0 != .*bash ]]; then echo Please source it: . $0 exit 1 fi res=`gradle --version \u003e/dev/null 2\u003e\u00261; echo $? ` if [[ $res == \"0\" ]]; then echo Have gradle: `which gradle` gradle --version else export GRADLE_HOME=~/opt/gradle export PATH=$PATH:$GRADLE_HOME/bin echo No Gradle, adding - `which gradle` gradle --version fi","title":"Pattern for test sourcing the script","type":"post"},{"content":"We have versioned repository ClientProvinceRepository that defines discount types based on account category pricelist and accounts - discountTypePriceList\n=\u0026gt; (let\u0026rsquo;s not start discussion why this is not part of the pricelists).\nThe item definition:\n\u0026lt;item-descriptor name=\u0026#34;discountTypePriceList\u0026#34; display-name=\u0026#34;Discount Type Price List\u0026#34; item-cache-size=\u0026#34;1000\u0026#34; query-cache-size=\u0026#34;1000\u0026#34; display-property=\u0026#34;discountType\u0026#34;\u0026gt; \u0026lt;table name=\u0026#34;CPLXB2B_DISCOUNT_PRICE_LIST\u0026#34; type=\u0026#34;primary\u0026#34; id-column-name=\u0026#34;DISCOUNT_PRICELIST_ID\u0026#34; \u0026gt; \u0026lt;property name=\u0026#34;discountType\u0026#34; data-type=\u0026#34;enumerated\u0026#34; column-name=\u0026#34;DISCOUNT_TYPE\u0026#34; default=\u0026#34;Base\u0026#34; queryable=\u0026#34;true\u0026#34; category=\u0026#34;Discount Price List\u0026#34; display-name=\u0026#34;Discount Type\u0026#34; \u0026gt; \u0026lt;attribute name=\u0026#34;useCodeForValue\u0026#34; value=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Base\u0026#34; code=\u0026#34;0\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Silver\u0026#34; code=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Gold\u0026#34; code=\u0026#34;2\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Platinum\u0026#34; code=\u0026#34;3\u0026#34;/\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;priceListId\u0026#34; column-name=\u0026#34;PRICE_LIST_ID\u0026#34; repository=\u0026#34;/atg/commerce/pricing/priceLists/PriceLists\u0026#34; item-type=\u0026#34;priceList\u0026#34; display-name=\u0026#34;List Price List\u0026#34; required=\u0026#34;true\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;salePriceListId\u0026#34; column-name=\u0026#34;SALE_PRICE_LIST_ID\u0026#34; repository=\u0026#34;/atg/commerce/pricing/priceLists/PriceLists\u0026#34; item-type=\u0026#34;priceList\u0026#34; display-name=\u0026#34;Sale Price List\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;startDate\u0026#34; column-name=\u0026#34;START_DATE\u0026#34; data-type=\u0026#34;timestamp\u0026#34; display-name=\u0026#34;Start Date\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;endDate\u0026#34; column-name=\u0026#34;END_DATE\u0026#34; data-type=\u0026#34;timestamp\u0026#34; display-name=\u0026#34;End Date\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;/table\u0026gt; \u0026lt;/item-descriptor\u0026gt; When I tried deployment with this, I got error\n13:39:28,476 INFO [DeploymentManager] The property named priceListId in the /client/b2b/commerce/province/repository/clientProvinceRepository_production repository has a reference to another repository /atg/commerce/pricing/priceLists/PriceLists. Be sure that the foreign property reference is configured correctly in the destination repository. The reference needs to point to the mapped destination repository and not the repository that is mapped in the source. 13:39:28,478 ERROR [DeploymentManager] atg.repository.RepositoryException: A repository misconfiguration has been detected. The property named priceListId in the /client/b2b/commerce/province/repository/clientProvinceRepository_production destination repository has a reference to source repository /atg/commerce/pricing/priceLists/PriceLists. This property has a reference to a foreign repository which should be configured to a destination repository and not a source repository. at atg.deployment.repository.ReferenceItemGenerator.generateDummyItems(ReferenceItemGenerator.java:254) at atg.deployment.repository.RepositoryWorkerThread.preDeploymentPhase(RepositoryWorkerThread.java:536) at atg.deployment.DeploymentWorkerThread.run(DeploymentWorkerThread.java:310) 13:39:28,499 ERROR [DeploymentManager] item = null cause = atg.repository.RepositoryException: A repository misconfiguration has been detected. The property named priceListId in the /client/b2b/commerce/province/repository/clientProvinceRepository_production destination repository has a reference to source repository /atg/commerce/pricing/priceLists/PriceLists. This property has a reference to a foreign repository which should be configured to a destination repository and not a source repository. at atg.deployment.repository.ReferenceItemGenerator.generateDummyItems(ReferenceItemGenerator.java:254) at atg.deployment.repository.RepositoryWorkerThread.preDeploymentPhase(RepositoryWorkerThread.java:536) at atg.deployment.DeploymentWorkerThread.run(DeploymentWorkerThread.java:310) message = An error occurred during the pre-deployment phase time = 2013-03-09 atg.deployment.DeploymentFailure@30b36590 What this means (in my interpretation) is that in MGMT node the /atg/commerce/pricing/priceLists/PriceLists is actually source repo (versioned), and the destination is /atg/commerce/pricing/priceLists/PriceLists_production.\nI added the following to the MGMT configuration - replaced the item descriptor with references to non-versioned repository /client-ca/config/client/b2b/commerce/province/repository/clientProvinceRepository.xml\n\u0026lt;item-descriptor name=\u0026#34;discountTypePriceList\u0026#34; display-name=\u0026#34;Discount Type Price List\u0026#34; item-cache-size=\u0026#34;1000\u0026#34; query-cache-size=\u0026#34;1000\u0026#34; display-property=\u0026#34;discountType\u0026#34; xml-combine=\u0026#34;replace\u0026#34;\u0026gt; \u0026lt;table name=\u0026#34;CPLXB2B_DISCOUNT_PRICE_LIST\u0026#34; type=\u0026#34;primary\u0026#34; id-column-name=\u0026#34;DISCOUNT_PRICELIST_ID\u0026#34; \u0026gt; \u0026lt;property name=\u0026#34;discountType\u0026#34; data-type=\u0026#34;enumerated\u0026#34; column-name=\u0026#34;DISCOUNT_TYPE\u0026#34; default=\u0026#34;Base\u0026#34; queryable=\u0026#34;true\u0026#34; category=\u0026#34;Discount Price List\u0026#34; display-name=\u0026#34;Discount Type\u0026#34; \u0026gt; \u0026lt;attribute name=\u0026#34;useCodeForValue\u0026#34; value=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Base\u0026#34; code=\u0026#34;0\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Silver\u0026#34; code=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Gold\u0026#34; code=\u0026#34;2\u0026#34;/\u0026gt; \u0026lt;option value=\u0026#34;Platinum\u0026#34; code=\u0026#34;3\u0026#34;/\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;property name=\u0026#34;priceListId\u0026#34; column-name=\u0026#34;PRICE_LIST_ID\u0026#34; repository=\u0026#34;/atg/commerce/pricing/priceLists/PriceLists_production\u0026#34; item-type=\u0026#34;priceList\u0026#34; display-name=\u0026#34;List Price List\u0026#34; required=\u0026#34;true\u0026#34; category=\u0026#34;Discount Price List\u0026#34; /\u0026gt; \u0026lt;property name=\u0026#34;salePriceListId\u0026#34; column-name=\u0026#34;SALE_PRICE_LIST_ID\u0026#34; repository=\u0026#34;/atg/commerce/pricing/priceLists/PriceLists_production\u0026#34; item-type=\u0026#34;priceList\u0026#34; display-name=\u0026#34;Sale Price List\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;startDate\u0026#34; column-name=\u0026#34;START_DATE\u0026#34; data-type=\u0026#34;timestamp\u0026#34; display-name=\u0026#34;Start Date\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;property name=\u0026#34;endDate\u0026#34; column-name=\u0026#34;END_DATE\u0026#34; data-type=\u0026#34;timestamp\u0026#34; display-name=\u0026#34;End Date\u0026#34; category=\u0026#34;Discount Price List\u0026#34;/\u0026gt; \u0026lt;/table\u0026gt; \u0026lt;/item-descriptor\u0026gt; This allowed the deployement to go through, however, now I see these in log file during deployment:\n19:48:54,966 INFO [DeploymentManager] The property named priceListId in the /client/b2b/commerce/province/repository/clientProvinceRepository_production repository has a reference to another repository /atg/commerce/pricing/priceLists/PriceLists_production. Be sure that the foreign property reference is configured correctly in the destination repository. The reference needs to point to the mapped destination repository and not the repository that is mapped in the source. 19:48:54,966 INFO [DeploymentManager] The property named priceListId in the /client/b2b/commerce/province/repository/clientProvinceRepository_production versioned repository references the unversioned repository /atg/commerce/pricing/priceLists/PriceLists_production. Verify that all the data in the unversioned repository exists on the target server, otherwise deployments which reference this data will fail. Questions # How serious is the message ? Is there better way ? If yes, what is proper way to deal with this (other than moving the item to pricelists repo ?) Note # As Joel pointed out (thanks), I have checked the RepositoryMapper and found that client does not have one.\nThis is how it is configured in client2:\nUsers/miro/src/TWC/client2/Management/config/atg/repository/ProductionRepositoryMapper.properties: 1: repositoryMappings+=\\ 2 /client2/repository/ContentRepository=/client2/repository/ContentRepository_production,\\ 3 /client2/repository/OperationsRepository=/client2/repository/OperationsRepository_production All client has is the OOTB values in this, no custom repos were (ever) added.\nThis guide http://docs.oracle.com/cd/E23507_01/Platform.20073/ATGBCCAdminGuide/html/s0203configuringforeignrepositoryrefe01.html explains what and hows.\n","date":"March 10, 2013","externalUrl":null,"permalink":"/posts/2013-03-10-atg-repository/","section":"Posts","summary":"We have versioned repository ClientProvinceRepository that defines discount types based on account category pricelist and accounts - discountTypePriceList\n=\u003e (let’s not start discussion why this is not part of the pricelists).\nThe item definition:\n\u003citem-descriptor name=\"discountTypePriceList\" display-name=\"Discount Type Price List\" item-cache-size=\"1000\" query-cache-size=\"1000\" display-property=\"discountType\"\u003e \u003ctable name=\"CPLXB2B_DISCOUNT_PRICE_LIST\" type=\"primary\" id-column-name=\"DISCOUNT_PRICELIST_ID\" \u003e \u003cproperty name=\"discountType\" data-type=\"enumerated\" column-name=\"DISCOUNT_TYPE\" default=\"Base\" queryable=\"true\" category=\"Discount Price List\" display-name=\"Discount Type\" \u003e \u003cattribute name=\"useCodeForValue\" value=\"false\"/\u003e \u003coption value=\"Base\" code=\"0\"/\u003e \u003coption value=\"Silver\" code=\"1\"/\u003e \u003coption value=\"Gold\" code=\"2\"/\u003e \u003coption value=\"Platinum\" code=\"3\"/\u003e \u003c/property\u003e \u003cproperty name=\"priceListId\" column-name=\"PRICE_LIST_ID\" repository=\"/atg/commerce/pricing/priceLists/PriceLists\" item-type=\"priceList\" display-name=\"List Price List\" required=\"true\" category=\"Discount Price List\"/\u003e \u003cproperty name=\"salePriceListId\" column-name=\"SALE_PRICE_LIST_ID\" repository=\"/atg/commerce/pricing/priceLists/PriceLists\" item-type=\"priceList\" display-name=\"Sale Price List\" category=\"Discount Price List\"/\u003e \u003cproperty name=\"startDate\" column-name=\"START_DATE\" data-type=\"timestamp\" display-name=\"Start Date\" category=\"Discount Price List\"/\u003e \u003cproperty name=\"endDate\" column-name=\"END_DATE\" data-type=\"timestamp\" display-name=\"End Date\" category=\"Discount Price List\"/\u003e \u003c/table\u003e \u003c/item-descriptor\u003e When I tried deployment with this, I got error\n","title":"ATG Repository item linking and versioned repos","type":"post"},{"content":"Suddenly I started to see all apps auf Deutsch:\nThe cause was by mistake selecting additional language in Properties -\u0026gt; Internationalization (Österreichisches Deutsch) and the system added it to the list as language #1.\nThose programs that are localized, picked it up \u0026hellip;.\nHere is how that list looks like after reorder :-) I care only for the first 11 languages anyway ;-)\n","date":"March 5, 2013","externalUrl":null,"permalink":"/posts/2013-03-05-german-attack/","section":"Posts","summary":"Suddenly I started to see all apps auf Deutsch:\nThe cause was by mistake selecting additional language in Properties -\u003e Internationalization (Österreichisches Deutsch) and the system added it to the list as language #1.\nThose programs that are localized, picked it up ….\nHere is how that list looks like after reorder :-) I care only for the first 11 languages anyway ;-)\n","title":"German attack","type":"post"},{"content":" New MacMini # MacMini:~ mediaserver$ mkdir .vim MacMini:~ mediaserver$ git clone git@github.com:radegast/dotvim.git .vim Cloning into \u0026#39;.vim\u0026#39;... The authenticity of host \u0026#39;github.com (207.97.227.239)\u0026#39; can\u0026#39;t be established. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added \u0026#39;github.com,207.97.227.239\u0026#39; (RSA) to the list of known hosts. remote: Counting objects: 367, done. remote: Compressing objects: 100% (309/309), done. remote: Total 367 (delta 58), reused 335 (delta 26) Receiving objects: 100% (367/367), 512.73 KiB, done. Resolving deltas: 100% (58/58), done. MacMini:~ mediaserver$ cd .vim MacMini:.vim mediaserver$ pwd /Users/mediaserver/.vim MacMini:.vim mediaserver$ ln -s ~/.vim/_vimrc ~/.vim .vim/ .viminfo MacMini:.vim mediaserver$ ln -s ~/.vim/_vimrc ~/.vimrc MacMini:.vim mediaserver$ ln -s ~/.vim/_gvimrc ~/.gvimrc MacMini:.vim mediaserver$ pwd /Users/mediaserver/.vim MacMini:.vim mediaserver$ git submodule init Submodule \u0026#39;bundle/tlib_vim\u0026#39; (git://github.com/tomtom/tlib_vim.git) registered for path \u0026#39;bundle/tlib_vim\u0026#39; Submodule \u0026#39;bundle/vim-fugitive\u0026#39; (git://github.com/tpope/vim-fugitive.git) registered for path \u0026#39;bundle/vim-fugitive\u0026#39; Submodule \u0026#39;bundle/vim-pathogen\u0026#39; (git://github.com/tpope/vim-pathogen.git) registered for path \u0026#39;bundle/vim-pathogen\u0026#39; Submodule \u0026#39;bundle/vim-unimpaired\u0026#39; (git://github.com/tpope/vim-unimpaired.git) registered for path \u0026#39;bundle/vim-unimpaired\u0026#39; MacMini:.vim mediaserver$ git submodule update Cloning into \u0026#39;bundle/tlib_vim\u0026#39;... remote: Counting objects: 992, done. remote: Compressing objects: 100% (372/372), done. remote: Total 992 (delta 594), reused 946 (delta 549) Receiving objects: 100% (992/992), 210.90 KiB, done. Resolving deltas: 100% (594/594), done. Submodule path \u0026#39;bundle/tlib_vim\u0026#39;: checked out \u0026#39;d66948917ce7153e4a961aa5d57e1b0918e20495\u0026#39; Cloning into \u0026#39;bundle/vim-fugitive\u0026#39;... remote: Counting objects: 1481, done. remote: Compressing objects: 100% (525/525), done. remote: Total 1481 (delta 637), reused 1405 (delta 579) Receiving objects: 100% (1481/1481), 190.02 KiB, done. Resolving deltas: 100% (637/637), done. Submodule path \u0026#39;bundle/vim-fugitive\u0026#39;: checked out \u0026#39;1b7e4070f5f7b7522422f5b00a75b323cc314daf\u0026#39; Cloning into \u0026#39;bundle/vim-pathogen\u0026#39;... remote: Counting objects: 395, done. remote: Compressing objects: 100% (215/215), done. remote: Total 395 (delta 108), reused 372 (delta 90) Receiving objects: 100% (395/395), 47.73 KiB, done. Resolving deltas: 100% (108/108), done. Submodule path \u0026#39;bundle/vim-pathogen\u0026#39;: checked out \u0026#39;ab64b4ddd0c184a528780b498a0b0a5b40248f7c\u0026#39; Cloning into \u0026#39;bundle/vim-unimpaired\u0026#39;... remote: Counting objects: 260, done. remote: Compressing objects: 100% (118/118), done. remote: Total 260 (delta 84), reused 250 (delta 76) Receiving objects: 100% (260/260), 33.89 KiB, done. Resolving deltas: 100% (84/84), done. Submodule path \u0026#39;bundle/vim-unimpaired\u0026#39;: checked out \u0026#39;440629adb4051e5f9920704570d1ff0e88356dc2\u0026#39; Adding terminal shortcut \u0026lsquo;mvim\u0026rsquo; # It is packed in the tbz file. Move it to /usr/bin\nMacMini:.vim mediaserver$ cat ~/Downloads/MacVim-snapshot-66/mvim #!/bin/sh # # This shell script passes all its arguments to the binary inside the # MacVim.app application bundle. If you make links to this script as view, # gvim, etc., then it will peek at the name used to call it and set options # appropriately. # # Based on a script by Wout Mertens and suggestions from Laurent Bihanic. This # version is the fault of Benji Fisher, 16 May 2005 (with modifications by Nico # Weber and Bjorn Winckler, Aug 13 2007). # First, check \u0026#34;All the Usual Suspects\u0026#34; for the location of the Vim.app bundle. # You can short-circuit this by setting the VIM_APP_DIR environment variable # or by un-commenting and editing the following line: # VIM_APP_DIR=/Applications if [ -z \u0026#34;$VIM_APP_DIR\u0026#34; ] then myDir=\u0026#34;`dirname \u0026#34;$0\u0026#34;`\u0026#34; myAppDir=\u0026#34;$myDir/../Applications\u0026#34; for i in ~/Applications ~/Applications/vim $myDir $myDir/vim $myAppDir $myAppDir/vim /Applications /Applications/vim /Applications/Utilities /Applications/Utilities/vim; do if [ -x \u0026#34;$i/MacVim.app\u0026#34; ]; then VIM_APP_DIR=\u0026#34;$i\u0026#34; break fi done fi if [ -z \u0026#34;$VIM_APP_DIR\u0026#34; ] then echo \u0026#34;Sorry, cannot find MacVim.app. Try setting the VIM_APP_DIR environment variable to the directory containing MacVim.app.\u0026#34; exit 1 fi binary=\u0026#34;$VIM_APP_DIR/MacVim.app/Contents/MacOS/Vim\u0026#34; # Next, peek at the name used to invoke this script, and set options # accordingly. name=\u0026#34;`basename \u0026#34;$0\u0026#34;`\u0026#34; gui= opts= # GUI mode, implies forking case \u0026#34;$name\u0026#34; in m*|g*|rm*|rg*) gui=true ;; esac # Restricted mode case \u0026#34;$name\u0026#34; in r*) opts=\u0026#34;$opts -Z\u0026#34;;; esac # vimdiff, view, and ex mode case \u0026#34;$name\u0026#34; in *vimdiff) opts=\u0026#34;$opts -dO\u0026#34; ;; *view) opts=\u0026#34;$opts -R\u0026#34; ;; *ex) opts=\u0026#34;$opts -e\u0026#34; ;; esac # Last step: fire up vim. # The program should fork by default when started in GUI mode, but it does # not; we work around this when this script is invoked as \u0026#34;gvim\u0026#34; or \u0026#34;rgview\u0026#34; # etc., but not when it is invoked as \u0026#34;vim -g\u0026#34;. if [ \u0026#34;$gui\u0026#34; ]; then # Note: this isn\u0026#39;t perfect, because any error output goes to the # terminal instead of the console log. # But if you use open instead, you will need to fully qualify the # path names for any filenames you specify, which is hard. exec \u0026#34;$binary\u0026#34; -g $opts ${1:+\u0026#34;$@\u0026#34;} else exec \u0026#34;$binary\u0026#34; $opts ${1:+\u0026#34;$@\u0026#34;} fi MacMini:.vim mediaserver$ sudo mv ~/Downloads/MacVim-snapshot-66/mvim /usr/bin/ Password: MacMini:.vim mediaserver$ mvim aaa MacMini:.vim mediaserver$ ","date":"March 3, 2013","externalUrl":null,"permalink":"/posts/2013-03-03-dotvim/","section":"Posts","summary":"New MacMini # MacMini:~ mediaserver$ mkdir .vim MacMini:~ mediaserver$ git clone git@github.com:radegast/dotvim.git .vim Cloning into '.vim'... The authenticity of host 'github.com (207.97.227.239)' can't be established. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,207.97.227.239' (RSA) to the list of known hosts. remote: Counting objects: 367, done. remote: Compressing objects: 100% (309/309), done. remote: Total 367 (delta 58), reused 335 (delta 26) Receiving objects: 100% (367/367), 512.73 KiB, done. Resolving deltas: 100% (58/58), done. MacMini:~ mediaserver$ cd .vim MacMini:.vim mediaserver$ pwd /Users/mediaserver/.vim MacMini:.vim mediaserver$ ln -s ~/.vim/_vimrc ~/.vim .vim/ .viminfo MacMini:.vim mediaserver$ ln -s ~/.vim/_vimrc ~/.vimrc MacMini:.vim mediaserver$ ln -s ~/.vim/_gvimrc ~/.gvimrc MacMini:.vim mediaserver$ pwd /Users/mediaserver/.vim MacMini:.vim mediaserver$ git submodule init Submodule 'bundle/tlib_vim' (git://github.com/tomtom/tlib_vim.git) registered for path 'bundle/tlib_vim' Submodule 'bundle/vim-fugitive' (git://github.com/tpope/vim-fugitive.git) registered for path 'bundle/vim-fugitive' Submodule 'bundle/vim-pathogen' (git://github.com/tpope/vim-pathogen.git) registered for path 'bundle/vim-pathogen' Submodule 'bundle/vim-unimpaired' (git://github.com/tpope/vim-unimpaired.git) registered for path 'bundle/vim-unimpaired' MacMini:.vim mediaserver$ git submodule update Cloning into 'bundle/tlib_vim'... remote: Counting objects: 992, done. remote: Compressing objects: 100% (372/372), done. remote: Total 992 (delta 594), reused 946 (delta 549) Receiving objects: 100% (992/992), 210.90 KiB, done. Resolving deltas: 100% (594/594), done. Submodule path 'bundle/tlib_vim': checked out 'd66948917ce7153e4a961aa5d57e1b0918e20495' Cloning into 'bundle/vim-fugitive'... remote: Counting objects: 1481, done. remote: Compressing objects: 100% (525/525), done. remote: Total 1481 (delta 637), reused 1405 (delta 579) Receiving objects: 100% (1481/1481), 190.02 KiB, done. Resolving deltas: 100% (637/637), done. Submodule path 'bundle/vim-fugitive': checked out '1b7e4070f5f7b7522422f5b00a75b323cc314daf' Cloning into 'bundle/vim-pathogen'... remote: Counting objects: 395, done. remote: Compressing objects: 100% (215/215), done. remote: Total 395 (delta 108), reused 372 (delta 90) Receiving objects: 100% (395/395), 47.73 KiB, done. Resolving deltas: 100% (108/108), done. Submodule path 'bundle/vim-pathogen': checked out 'ab64b4ddd0c184a528780b498a0b0a5b40248f7c' Cloning into 'bundle/vim-unimpaired'... remote: Counting objects: 260, done. remote: Compressing objects: 100% (118/118), done. remote: Total 260 (delta 84), reused 250 (delta 76) Receiving objects: 100% (260/260), 33.89 KiB, done. Resolving deltas: 100% (84/84), done. Submodule path 'bundle/vim-unimpaired': checked out '440629adb4051e5f9920704570d1ff0e88356dc2' Adding terminal shortcut ‘mvim’ # It is packed in the tbz file. Move it to /usr/bin\n","title":"Dot-vimming new machine","type":"post"},{"content":"","date":"March 3, 2013","externalUrl":null,"permalink":"/tags/editor/","section":"Tags","summary":"","title":"Editor","type":"tags"},{"content":"I have been experiencing issues with Quicklook (press Space on file in Finder or Pathfinder) for some time: it took several second, sometimes 10-15 to show content of simple 1K large property file.\nIt turned out that on of the QuickLook plugins, installed originally way back in Leopard and brought ahead with TimeMachine restores could have been the reason: the QLStephen.\nFor more on that plugin see:\nhttp://whomwah.github.com/qlstephen/ https://github.com/whomwah/qlstephen To remove the plugin, go to ~/Library/QuickLook and delete the file (it is the bundle) QLStephen.qlgenerator.\nOptionally, you may want to restart the QuickLook daemon:\nqlmanage -r\nSee man qlmanage or qlmanage --help for more details\nAfter doing that, the response time on property files, XML and others went down to about 1 sec, which is more like one would expect on quad-core 8GB system\nBtw, the plugin system and the whole UTI seems to be approaching messyness of Registry.\nHere is what I see when I run the\nqlmanage -m plugins | sort | pbcopy com.adobe.encapsulated-postscript -\u0026gt; /System/Library/QuickLook/EPS.qlgenerator (500.18) com.adobe.illustrator.ai-image -\u0026gt; /System/Library/QuickLook/EPS.qlgenerator (500.18) com.adobe.pdf -\u0026gt; /System/Library/QuickLook/PDF.qlgenerator (500.18) com.alias.pix -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.alias.rasterimage -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.allume.stuffit-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.apple.addressbook.group -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Contact.qlgenerator (500.18) com.apple.addressbook.person -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Contact.qlgenerator (500.18) com.apple.application -\u0026gt; /System/Library/QuickLook/StandardBundles.qlgenerator (500.18) com.apple.binhex-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.apple.bom-compressed-cpio -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.apple.finder.pictclipping -\u0026gt; /System/Library/QuickLook/Clippings.qlgenerator (500.18) com.apple.finder.textclipping -\u0026gt; /System/Library/QuickLook/Clippings.qlgenerator (500.18) com.apple.garageband.project -\u0026gt; /Applications/GarageBand.app/Contents/Library/QuickLook/GBQLGenerator.qlgenerator (428.5) com.apple.garageband.template.magic -\u0026gt; /Applications/GarageBand.app/Contents/Library/QuickLook/GBQLGenerator.qlgenerator (428.5) com.apple.garageband.template.magicmentor -\u0026gt; /Applications/GarageBand.app/Contents/Library/QuickLook/GBQLGenerator.qlgenerator (428.5) com.apple.ibooksauthor.book -\u0026gt; /Applications/iBooks Author.app/Contents/Library/QuickLook/iBooksAuthor.qlgenerator (1.0) com.apple.ical.bookmark -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/iCal.qlgenerator (500.18) com.apple.ical.bookmark.todo -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/iCal.qlgenerator (500.18) com.apple.ical.ics -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/iCal.qlgenerator (500.18) com.apple.ical.ics.event -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/iCal.qlgenerator (500.18) com.apple.ical.ics.todo -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/iCal.qlgenerator (500.18) com.apple.ichat.ichat -\u0026gt; /System/Library/QuickLook/iChat.qlgenerator (1011) com.apple.ichat.transcript -\u0026gt; /System/Library/QuickLook/iChat.qlgenerator (1011) com.apple.iconset -\u0026gt; /System/Library/QuickLook/Icon.qlgenerator (500.18) com.apple.internet-location -\u0026gt; /System/Library/QuickLook/Clippings.qlgenerator (500.18) com.apple.iwork.keynote.key -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.iwork.keynote.sffkey -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.iwork.numbers.numbers -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.iwork.numbers.sffnumbers -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.iwork.pages.pages -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.iwork.pages.sffpages -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.keychain -\u0026gt; /System/Library/QuickLook/Security.qlgenerator (55022.6) com.apple.keynote.key -\u0026gt; /Library/QuickLook/iWork.qlgenerator (11) com.apple.localized-pdf-bundle -\u0026gt; /System/Library/QuickLook/LocPDF.qlgenerator (500.18) com.apple.macbinary-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.apple.mach-o-binary -\u0026gt; /Applications/Library Inspector.app/Contents/Library/QuickLook/Library Inspector Quick Look.qlgenerator (4) com.apple.mail.email -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Mail.qlgenerator (500.18) com.apple.mail.emlx -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Mail.qlgenerator (500.18) com.apple.package -\u0026gt; /System/Library/QuickLook/Package.qlgenerator (500.18) com.apple.pict -\u0026gt; /System/Library/QuickLook/Clippings.qlgenerator (500.18) com.apple.property-list -\u0026gt; /Users/miro/Library/QuickLook/QLColorCode.qlgenerator (2.0.1) com.apple.quartz-composer-composition -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/QuartzComposer.qlgenerator (500.18) com.apple.rtfd -\u0026gt; /System/Library/QuickLook/Text.qlgenerator (500.18) com.apple.safari.bookmark -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Bookmark.qlgenerator (500.18) com.apple.safari.history -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Bookmark.qlgenerator (500.18) com.apple.systempreference.prefpane -\u0026gt; /System/Library/QuickLook/StandardBundles.qlgenerator (500.18) com.apple.traditional-mac-plain-text -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) com.apple.webarchive -\u0026gt; /System/Library/QuickLook/Web.qlgenerator (500.18) com.avs.ximage -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.bruji.pediaimporter.book -\u0026gt; /Applications/Bookpedia.app/Contents/Library/QuickLook/QuickLookPedia.qlgenerator (1.0) com.bruji.pediaimporter.cd -\u0026gt; /Applications/Bookpedia.app/Contents/Library/QuickLook/QuickLookPedia.qlgenerator (1.0) com.bruji.pediaimporter.dvd -\u0026gt; /Applications/Bookpedia.app/Contents/Library/QuickLook/QuickLookPedia.qlgenerator (1.0) com.bruji.pediaimporter.game -\u0026gt; /Applications/Bookpedia.app/Contents/Library/QuickLook/QuickLookPedia.qlgenerator (1.0) com.ccitt.fax -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.culturedcode.thingsitem -\u0026gt; /Applications/Things.app/Contents/Library/QuickLook/ThingsQuickLookGenerator.qlgenerator (1.0) com.dicom.dicom -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.dmpe.dmpe -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.drhalo.drhalo -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.durrantsoftware.mobi -\u0026gt; /Library/QuickLook/QLMobipocket.qlgenerator (1.1) com.evernote.note-metadata -\u0026gt; /Applications/Evernote.app/Contents/Library/QuickLook/ENQuickLookGenerator.qlgenerator (1.0) com.fits.fits -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.flyingmeat.voodoopad.vpdoc -\u0026gt; /Applications/VoodooPad.app/Contents/Library/QuickLook/VoodooPad.qlgenerator (5.0) com.flyingmeat.voodoopad.vpspotlight -\u0026gt; /Applications/VoodooPad.app/Contents/Library/QuickLook/VoodooPad.qlgenerator (5.0) com.gimp.xcf -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.ibm.pcc -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.imagemagick.miff -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.imagemagick.mvg -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.jng.jng -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.khoros.viff -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.macitbetter.cbz-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.macitbetter.segmented-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.macitbetter.zip-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.microsoft.cab-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.microsoft.chm-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.microsoft.excel.xls -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.excel.xlt -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.powerpoint.pot -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.powerpoint.pps -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.powerpoint.ppt -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.word.doc -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.word.dot -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.microsoft.word.stationery -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) com.mng.mng -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.mtvraytracing.ray -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.omnigroup.omnigraffle.graffle -\u0026gt; /Applications/OmniGraffle Professional 5.app/Contents/Library/QuickLook/OmniGraffle.qlgenerator (3.0) com.omnigroup.omnigraffle.graffle-package -\u0026gt; /Applications/OmniGraffle Professional 5.app/Contents/Library/QuickLook/OmniGraffle.qlgenerator (3.0) com.omnigroup.omnigraffle.gstencil -\u0026gt; /Applications/OmniGraffle Professional 5.app/Contents/Library/QuickLook/OmniGraffle.qlgenerator (3.0) com.omnigroup.omnigraffle.gstencil-package -\u0026gt; /Applications/OmniGraffle Professional 5.app/Contents/Library/QuickLook/OmniGraffle.qlgenerator (3.0) com.ontheair.image -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.palm.pixmap -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pam.pam -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pbm.pbm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pcd.pcd -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pcx.pcx -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pfs.clipart -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pgm.pgm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.picon.picon -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pixelmator-team.image.webp -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pixelmator.pxg -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pixelmator.pxm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.pnm.pnm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.ppm.ppm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.psx.psx -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.rarlab.rar-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.redhat.rpm-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.rle.rle -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.rsa.pkcs-12 -\u0026gt; /System/Library/QuickLook/Security.qlgenerator (55022.6) com.scitex.image -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.sfwi.image -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.stuffit.archive.sit -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.sun.java-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.sun.raster -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.svg.svgz -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.symantec.diskdoubler-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) com.tastycocoabytes.cocoapacketanalyzer.document -\u0026gt; /Applications/CocoaPacketAnalyzer.app/Contents/Library/QuickLook/CPAQuickLook.qlgenerator (0.2) com.vical.raster -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.vmware.foreign.pvm -\u0026gt; /Applications/VMware Fusion.app/Contents/Library/QuickLook/VMware Fusion QuickLook.qlgenerator (900491) com.vmware.foreign.pvs -\u0026gt; /Applications/VMware Fusion.app/Contents/Library/QuickLook/VMware Fusion QuickLook.qlgenerator (900491) com.vmware.foreign.vhd -\u0026gt; /Applications/VMware Fusion.app/Contents/Library/QuickLook/VMware Fusion QuickLook.qlgenerator (900491) com.vmware.foreign.vpc7 -\u0026gt; /Applications/VMware Fusion.app/Contents/Library/QuickLook/VMware Fusion QuickLook.qlgenerator (900491) com.vmware.vm-package -\u0026gt; /Applications/VMware Fusion.app/Contents/Library/QuickLook/VMware Fusion QuickLook.qlgenerator (900491) com.wbmp.wbmp -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.wpg.wpg -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.xpm.xpm -\u0026gt; /Applications/Pixelmator.app/Contents/Library/QuickLook/PixelmatorLook.qlgenerator (1.31) com.zengobi.curio.ideaspace -\u0026gt; /Applications/Curio.app/Contents/Library/QuickLook/CurioQuickLook.qlgenerator (8002) com.zengobi.curio.project -\u0026gt; /Applications/Curio.app/Contents/Library/QuickLook/CurioQuickLook.qlgenerator (8002) dyn.age80g650 -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) dyn.ah62d4rv4ge80c -\u0026gt; /Applications/Library Inspector.app/Contents/Library/QuickLook/Library Inspector Quick Look.qlgenerator (4) dyn.ah62d4rv4ge80g650 -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) dyn.ah62d4rv4ge81k2pc -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) net.telestream.screenflow.document -\u0026gt; /Applications/ScreenFlow.app/Contents/Library/QuickLook/ScreenFlow.qlgenerator (1.0) nz.co.oriontransfer.library-inspector.archive -\u0026gt; /Applications/Library Inspector.app/Contents/Library/QuickLook/Library Inspector Quick Look.qlgenerator (4) org.7-zip.7-zip-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.7-zip.arj-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.7-zip.lha-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.7-zip.nsis-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.bzip.bzip2-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.bzip.bzip2-tar-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.debian.deb-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.gnu.gnu-zip-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.gnu.gnu-zip-tar-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) org.khronos.collada.digital-asset-exchange -\u0026gt; /System/Library/QuickLook/SceneKit.qlgenerator (125.8) org.oasis-open.opendocument.text -\u0026gt; /System/Library/QuickLook/Text.qlgenerator (500.18) org.openxmlformats.presentationml.presentation -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.presentationml.presentation.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.presentationml.slideshow -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.presentationml.slideshow.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.presentationml.template -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.presentationml.template.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.spreadsheetml.sheet -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.spreadsheetml.sheet.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.spreadsheetml.template -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.spreadsheetml.template.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.wordprocessingml.document -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.wordprocessingml.document.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.wordprocessingml.template -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.openxmlformats.wordprocessingml.template.macroenabled -\u0026gt; /System/Library/QuickLook/Office.qlgenerator (31.0) org.tug.tex -\u0026gt; /Users/miro/Library/QuickLook/QLColorCode.qlgenerator (2.0.1) public.archive.arj -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.archive.bzip2 -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.archive.cab -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.archive.lha -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.audio -\u0026gt; /System/Library/QuickLook/Audio.qlgenerator (500.18) public.bzip2-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.comma-separated-values-text -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) public.cpio-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.disk-image -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.folder -\u0026gt; /Library/QuickLook/Folder.qlgenerator (0.3) public.font -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Font.qlgenerator (500.18) public.html -\u0026gt; /System/Library/QuickLook/Web.qlgenerator (500.18) public.iso-diskimage -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.iso-image -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.movie -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Movie.qlgenerator (500.18) public.object-code -\u0026gt; /Applications/Library Inspector.app/Contents/Library/QuickLook/Library Inspector Quick Look.qlgenerator (4) public.plain-text -\u0026gt; /Users/miro/Library/QuickLook/QLColorCode.qlgenerator (2.0.1) public.rtf -\u0026gt; /System/Library/QuickLook/Text.qlgenerator (500.18) public.source-code -\u0026gt; /Users/miro/Library/QuickLook/QLColorCode.qlgenerator (2.0.1) public.svg-image -\u0026gt; /System/Library/QuickLook/Web.qlgenerator (500.18) public.tab-separated-values-text -\u0026gt; /Users/miro/Library/QuickLook/QuickLookCSV.qlgenerator (1.1.1) public.tar-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) public.vcard -\u0026gt; /System/Library/Frameworks/QuickLook.framework/PlugIns/Contact.qlgenerator (500.18) public.volume -\u0026gt; /Library/QuickLook/Folder.qlgenerator (0.3) public.x509-certificate -\u0026gt; /System/Library/QuickLook/Security.qlgenerator (55022.6) public.x509-printable-encoded-archive -\u0026gt; /System/Library/QuickLook/Security.qlgenerator (55022.6) public.xhtml -\u0026gt; /System/Library/QuickLook/Web.qlgenerator (500.18) public.xml -\u0026gt; /Users/miro/Library/QuickLook/QLColorCode.qlgenerator (2.0.1) public.zip-archive -\u0026gt; /Users/miro/Library/QuickLook/BetterZipQL.qlgenerator (1.2) ","date":"February 23, 2013","externalUrl":null,"permalink":"/posts/2013-02-23-perf-quicklook-lion/","section":"Posts","summary":"I have been experiencing issues with Quicklook (press Space on file in Finder or Pathfinder) for some time: it took several second, sometimes 10-15 to show content of simple 1K large property file.\nIt turned out that on of the QuickLook plugins, installed originally way back in Leopard and brought ahead with TimeMachine restores could have been the reason: the QLStephen.\nFor more on that plugin see:\nhttp://whomwah.github.com/qlstephen/ https://github.com/whomwah/qlstephen To remove the plugin, go to ~/Library/QuickLook and delete the file (it is the bundle) QLStephen.qlgenerator.\n","title":"Performance issues with Quicklook in OS-X Lion","type":"post"},{"content":"Installed GVM from:\nhttp://gvmtool.net\n~ $ curl -s get.gvmtool.net | bash Thanks for using _____/\\\\\\\\\\\\\\\\\\\\\\\\__/\\\\\\________/\\\\\\__/\\\\\\\\____________/\\\\\\\\_ ___/\\\\\\//////////__\\/\\\\\\_______\\/\\\\\\_\\/\\\\\\\\\\\\________/\\\\\\\\\\\\_ __/\\\\\\_____________\\//\\\\\\______/\\\\\\__\\/\\\\\\//\\\\\\____/\\\\\\//\\\\\\_ _\\/\\\\\\____/\\\\\\\\\\\\\\__\\//\\\\\\____/\\\\\\___\\/\\\\\\\\///\\\\\\/\\\\\\/_\\/\\\\\\_ _\\/\\\\\\___\\/////\\\\\\___\\//\\\\\\__/\\\\\\____\\/\\\\\\__\\///\\\\\\/___\\/\\\\\\_ _\\/\\\\\\_______\\/\\\\\\____\\//\\\\\\/\\\\\\_____\\/\\\\\\____\\///_____\\/\\\\\\_ _\\/\\\\\\_______\\/\\\\\\_____\\//\\\\\\\\\\______\\/\\\\\\_____________\\/\\\\\\_ _\\//\\\\\\\\\\\\\\\\\\\\\\\\/_______\\//\\\\\\_______\\/\\\\\\_____________\\/\\\\\\_ __\\////////////__________\\///________\\///______________\\///__ Will now attempt installing... Looking for a previous installation of GVM... Looking for JAVA_HOME... Validating JAVA_HOME... Looking for unzip... Looking for curl... Installing gvm scripts... Create distribution directories... Create candidate directories... Download script archive... Extract script archive... Install scripts... Make init script executable... Prime config file... Attempt update of bash profiles... Updated existing /Users/miro/.bash_profile Updated existing /Users/miro/.profile Updated existing /Users/miro/.bashrc Attempt update of zsh profiles... Created and initialised /Users/miro/.zshrc Clean up local variables... All done! Please open a new terminal, or run the following in the existing one: source \u0026#34;/Users/miro/.gvm/bin/gvm-init.sh\u0026#34; Then issue the following command: gvm help Enjoy!!! Using # binsh $ gvm current Using: groovy: 2.0.6 grails: 2.2.0 griffon: 1.1.0 gradle: 1.3 vertx: 1.3.0.final Fix for zsh # http://blog.andresteingress.com/2012/12/14/gvm-the-groovy-environment-manager/\ncineplex $ cat ~/.zshrc #THIS MUST BE AT THE END OF THE FILE FOR GVM TO WORK!!! # [[ -s \u0026#34;/Users/miro/.gvm/bin/gvm-init.sh\u0026#34; \u0026amp;\u0026amp; ! $(which gvm-init.sh) ]] \u0026amp;\u0026amp; source \u0026#34;/Users/miro/.gvm/bin/gvm-init.sh\u0026#34; source \u0026#34;/Users/miro/.gvm/bin/gvm-init.sh\u0026#34; ","date":"January 8, 2013","externalUrl":null,"permalink":"/posts/2013-01-08-gvm/","section":"Posts","summary":"Installed GVM from:\nhttp://gvmtool.net\n~ $ curl -s get.gvmtool.net | bash Thanks for using _____/\\\\\\\\\\\\\\\\\\\\\\\\__/\\\\\\________/\\\\\\__/\\\\\\\\____________/\\\\\\\\_ ___/\\\\\\//////////__\\/\\\\\\_______\\/\\\\\\_\\/\\\\\\\\\\\\________/\\\\\\\\\\\\_ __/\\\\\\_____________\\//\\\\\\______/\\\\\\__\\/\\\\\\//\\\\\\____/\\\\\\//\\\\\\_ _\\/\\\\\\____/\\\\\\\\\\\\\\__\\//\\\\\\____/\\\\\\___\\/\\\\\\\\///\\\\\\/\\\\\\/_\\/\\\\\\_ _\\/\\\\\\___\\/////\\\\\\___\\//\\\\\\__/\\\\\\____\\/\\\\\\__\\///\\\\\\/___\\/\\\\\\_ _\\/\\\\\\_______\\/\\\\\\____\\//\\\\\\/\\\\\\_____\\/\\\\\\____\\///_____\\/\\\\\\_ _\\/\\\\\\_______\\/\\\\\\_____\\//\\\\\\\\\\______\\/\\\\\\_____________\\/\\\\\\_ _\\//\\\\\\\\\\\\\\\\\\\\\\\\/_______\\//\\\\\\_______\\/\\\\\\_____________\\/\\\\\\_ __\\////////////__________\\///________\\///______________\\///__ Will now attempt installing... Looking for a previous installation of GVM... Looking for JAVA_HOME... Validating JAVA_HOME... Looking for unzip... Looking for curl... Installing gvm scripts... Create distribution directories... Create candidate directories... Download script archive... Extract script archive... Install scripts... Make init script executable... Prime config file... Attempt update of bash profiles... Updated existing /Users/miro/.bash_profile Updated existing /Users/miro/.profile Updated existing /Users/miro/.bashrc Attempt update of zsh profiles... Created and initialised /Users/miro/.zshrc Clean up local variables... All done! Please open a new terminal, or run the following in the existing one: source \"/Users/miro/.gvm/bin/gvm-init.sh\" Then issue the following command: gvm help Enjoy!!! Using # binsh $ gvm current Using: groovy: 2.0.6 grails: 2.2.0 griffon: 1.1.0 gradle: 1.3 vertx: 1.3.0.final Fix for zsh # http://blog.andresteingress.com/2012/12/14/gvm-the-groovy-environment-manager/\n","title":"GVM","type":"post"},{"content":"Finally a todo/task/project management system that is very good fit.\nHere is why:\nis pretty visually modern and dynamic UI has Web back-end (usable from Linux VM) has decent iPhone app allows checklists (multiple) allows color coding Markdown support ecosystem There is Gmello that allows create card from GMail, plus few others that seem to bridge the gap between Evernote, System XYZ and Trello\nhttp://trello.com\nCourtesy of Fog Creek / Joel Spolsky\u0026rsquo;s company\n","date":"November 12, 2012","externalUrl":null,"permalink":"/posts/2012-11-12-trello/","section":"Posts","summary":"Finally a todo/task/project management system that is very good fit.\nHere is why:\nis pretty visually modern and dynamic UI has Web back-end (usable from Linux VM) has decent iPhone app allows checklists (multiple) allows color coding Markdown support ecosystem There is Gmello that allows create card from GMail, plus few others that seem to bridge the gap between Evernote, System XYZ and Trello\nhttp://trello.com\nCourtesy of Fog Creek / Joel Spolsky’s company\n","title":"Discovered Trello","type":"post"},{"content":"OK, NERDTree plugin IS great, but this is awesome.\nAlloy made custom version of MacVim with file drawer: see https://github.com/alloy/macvim/wiki/Building\nIt is available in source - so you have to compile it yourselves. But if you do not want to, I did it and the binary is attached, built with these features:\n./configure \u0026ndash;with-feature=huge \u0026ndash;enable-rubyinterp \u0026ndash;enable-pythoninterp \u0026ndash;enable-perlinterp \u0026ndash;enable-cscope\nArchive is attached: MacVim.zip\nIf you want to get my set of plugins and customizations, it is on GitHub: - https://github.com/radegast/dotvim,\nDocumentation files tells it all:\nhttps://github.com/radegast/dotvim/blob/master/README.md https://github.com/radegast/dotvim/blob/master/ModuleInfo.md https://github.com/radegast/dotvim/blob/master/Versions.md Here is a screenshot # ","date":"October 7, 2012","externalUrl":null,"permalink":"/posts/2012-10-07-macvim/","section":"Posts","summary":"OK, NERDTree plugin IS great, but this is awesome.\nAlloy made custom version of MacVim with file drawer: see https://github.com/alloy/macvim/wiki/Building\nIt is available in source - so you have to compile it yourselves. But if you do not want to, I did it and the binary is attached, built with these features:\n./configure –with-feature=huge –enable-rubyinterp –enable-pythoninterp –enable-perlinterp –enable-cscope\nArchive is attached: MacVim.zip\nIf you want to get my set of plugins and customizations, it is on GitHub: - https://github.com/radegast/dotvim,\n","title":"Custom build of MacVim with file drawer - pure bliss","type":"post"},{"content":"After update, the ST2 started to complain about missing git command.\nFinding out Git on MBP:\nplatform $ which git git is /usr/bin/git git is /usr/local/bin/git platform $ git --version git version 1.7.7.5 (Apple Git-26) platform $ /usr/bin/git --version git version 1.7.7.5 (Apple Git-26) platform $ /usr/local/bin/git --version git version 1.7.3.2 Fix the the Package file in /Users/miro/Library/Application Support/Sublime Text 2/Packages/Git - Git.sublime-settings (it is JSON file)\n{ // save before running commands \u0026#34;save_first\u0026#34;: true // if present, use this command instead of plain \u0026#34;git\u0026#34; // e.g. \u0026#34;/Users/kemayo/bin/git\u0026#34; or \u0026#34;C:\\bin\\git.exe\u0026#34; ,\u0026#34;git_command\u0026#34;: \u0026#34;/usr/local/bin/git\u0026#34; .... Also, I had to delete the *.sublime_session from /Users/miro/Library/Application Support/Sublime Text 2/Settings\n","date":"September 21, 2012","externalUrl":null,"permalink":"/posts/2012-09-21-post/","section":"Posts","summary":"After update, the ST2 started to complain about missing git command.\nFinding out Git on MBP:\nplatform $ which git git is /usr/bin/git git is /usr/local/bin/git platform $ git --version git version 1.7.7.5 (Apple Git-26) platform $ /usr/bin/git --version git version 1.7.7.5 (Apple Git-26) platform $ /usr/local/bin/git --version git version 1.7.3.2 Fix the the Package file in /Users/miro/Library/Application Support/Sublime Text 2/Packages/Git - Git.sublime-settings (it is JSON file)\n","title":"Fixing Git plugin for Sublime Text 2","type":"post"},{"content":"","date":"August 17, 2012","externalUrl":null,"permalink":"/tags/hybris/","section":"Tags","summary":"","title":"Hybris","type":"tags"},{"content":" Installing and running \u0026ldquo;naked\u0026rdquo; hybris platform # Log of an exercise to install and start the Hybris without all those fancy modules\nStarting point: hybris-platform-4.7.1.zip\nInstall point: /opt/hybris-platform/hybris-platform-4.7.1\nStart (with HSQLdb) # ~ $ cd /opt/hybris-platform/hybris-platform-4.7.1 hybris-platform-4.7.1 $ cd bin/platform/ platform $ pwd /opt/hybris-platform/hybris-platform-4.7.1/bin/platform platform $ . ./setantenv.sh Setting ant home to: /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/apache-ant-1.8.2 Apache Ant(TM) version 1.8.2 compiled on April 21 2011 platform $ ant clean all | tee ant-clean-all.log =\u0026gt; Select develop\n.... .... [echo] [jspcompile] compiling.. /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6/work/Catalina/localhost/hmc [yjavac] Compiling 205 source files to /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6/work/Catalina/localhost/hmc [touch] Creating /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6/work/Catalina/localhost/hmc/jspcompile_touch [stopwatch] [build: 43.686 sec] server: [echo] [echo] Configuring server at /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6 [echo] Using config set at /opt/hybris-platform/hybris-platform-4.7.1/config/tomcat [echo] [mkdir] Created dir: /opt/hybris-platform/hybris-platform-4.7.1/log/tomcat [mkdir] Created dir: /opt/hybris-platform/hybris-platform-4.7.1/data/media [copy] Copying 8 files to /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6 [copy] Copying 6 files to /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6 [copy] Copying 1 file to /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/tomcat-6/lib [echo] [echo] Embedded server does not seem to be running (no PID found). No restart necessary. [echo] all: [echo] Build finished on 17-August-2012 19:43:22. [echo] BUILD SUCCESSFUL Total time: 1 minute 26 seconds Goto http://localhost:9001/ - redirects to http://localhost:9001/platform/init\nList of modules that goes up: # core hmc servicelayer task commons cronjob lucenesearch impex validation variants europe1 category catalog virtualjdbc platformservices workflow processengine ldap comments cockpit mcc advancedsavedquery admincockpit Initialization log # Initialization Dropping ALL tables ... Initialize system ... Please wait. This step can take some minutes to complete. If you do not receive any feedback on this page in this time, consult the applicationserver logs for possible errors. Dropping old and creating new empty system ... \u0026gt;\u0026gt;\u0026gt; Remove objects ... \u0026gt;\u0026gt;\u0026gt; Create types ... \u0026gt;\u0026gt;\u0026gt; Modify types ... \u0026gt;\u0026gt;\u0026gt; Create objects ... \u0026gt;\u0026gt;\u0026gt; Setting licence ... Restarting tenant ... Clearing hmc configuration from database ... Creating essential data ... Creating essential data for core ... Creating essential data for mediaweb ... Creating essential data for maintenanceweb ... Creating essential data for hmc ... Creating essential data for servicelayer ... Creating essential data for task ... Creating essential data for paymentstandard ... Creating essential data for deliveryzone ... Creating essential data for commons ... Creating essential data for cronjob ... Creating essential data for lucenesearch ... Creating essential data for impex ... Creating essential data for validation ... Creating essential data for variants ... Creating essential data for europe1 ... Creating essential data for category ... Creating essential data for catalog ... Creating essential data for virtualjdbc ... Creating essential data for platformservices ... Creating essential data for workflow ... Creating essential data for processengine ... Creating essential data for platformwebservices ... Creating essential data for ldap ... Creating essential data for hac ... Creating essential data for comments ... Creating essential data for cockpit ... Creating essential data for mcc ... Creating essential data for advancedsavedquery ... Creating essential data for admincockpit ... Localizing types ... Creating project data ... Creating project data for core ... Creating project data for hmc ... Creating project data for servicelayer ... Creating project data for task ... Creating project data for commons ... Creating project data for cronjob ... Creating project data for lucenesearch ... Creating project data for impex ... Creating project data for validation ... Creating project data for variants ... Creating project data for europe1 ... Creating project data for category ... Creating project data for catalog ... Creating project data for virtualjdbc ... Creating project data for platformservices ... Creating project data for workflow ... Creating project data for processengine ... Creating project data for ldap ... Creating project data for comments ... Creating project data for cockpit ... Creating project data for mcc ... Creating project data for advancedsavedquery ... Creating project data for admincockpit ... FINISHED. The initialization took: 0d 00h:01m:08s:235ms Exploring # look at the configuration parameters under http://localhost:9001/platform/config logging - http://localhost:9001/platform/log4j All loaded extensions - with their Web apps: http://localhost:9001/platform/extensions http://localhost:9001/virtualjdbc/ AdminCockpit: http://localhost:9001/admincockpit/index.zul MultiChannel Cockpit - http://localhost:9001/mcc/index.zul Hybris Management Console - http://localhost:9001/hmc/hybris?wid=MC0x0\u0026amp;prgrequest=true\u0026amp;MC0x2_!DISPLAY=MC0x12 Maintenance page: http://localhost:9001/maintenance/ Medias (??) http://localhost:9001/medias/ WS - http://localhost:9001/ws410/ Sample data must be loaded ? Q: How do I load sample data ? REST Client # $ cd /opt/restClient/ restClient $ ll total 44280 -rw-r--r--@ 1 miro staff 8.4M 17 Aug 20:15 restclient-cli-2.5-jar-with-dependencies.jar -rw-r--r--@ 1 miro staff 13M 17 Aug 20:16 restclient-ui-2.5-jar-with-dependencies.jar restClient $ java -jar restclient-ui-2.5-jar-with-dependencies.jar must enter admin/nimda into tool\nFollow http://localhost:9001/ws410/rest/countries\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; standalone=\u0026#34;yes\u0026#34;?\u0026gt; \u0026lt;countries xmlns:ns2=\u0026#34;http://wadl.dev.java.net/2009/02\u0026#34; uri=\u0026#34;http://localhost:9001/ws410/rest/countries\u0026#34;\u0026gt; \u0026lt;country isocode=\u0026#34;DE\u0026#34; pk=\u0026#34;8796093055010\u0026#34; uri=\u0026#34;http://localhost:9001/ws410/rest/countries/DE\u0026#34;/\u0026gt; \u0026lt;/countries\u0026gt; Interesting catalog tool - comparison:\nhttp://localhost:9001/hmc/hybris?wid=MC1x745\u0026prgrequest=true\u0026null Admin Cockpit # http://localhost:9001/admincockpit/index.zul\nVirtual JDBC # Available at http://localhost:9001/virtualjdbc/\nThis extension offers the functionality to connect to a database using a virtual JDBC connection. This allows to create reports in real-time on live data without risks of corrupting data.\nTo connect via HTTP the jdbc url looks like:\n[jdbc:hybris:sql:http://localhost:9001/virtualjdbc/service]() [jdbc:hybris:flexiblesearch:http://localhost:9001/virtualjdbc/service;tenant=master]() Detailed documentation can be found at virtualjdbc Extension.\n","date":"August 17, 2012","externalUrl":null,"permalink":"/posts/2012-08-17-install-hybris/","section":"Posts","summary":"Installing and running “naked” hybris platform # Log of an exercise to install and start the Hybris without all those fancy modules\nStarting point: hybris-platform-4.7.1.zip\nInstall point: /opt/hybris-platform/hybris-platform-4.7.1\nStart (with HSQLdb) # ~ $ cd /opt/hybris-platform/hybris-platform-4.7.1 hybris-platform-4.7.1 $ cd bin/platform/ platform $ pwd /opt/hybris-platform/hybris-platform-4.7.1/bin/platform platform $ . ./setantenv.sh Setting ant home to: /opt/hybris-platform/hybris-platform-4.7.1/bin/platform/apache-ant-1.8.2 Apache Ant(TM) version 1.8.2 compiled on April 21 2011 platform $ ant clean all | tee ant-clean-all.log =\u003e Select develop\n","title":"Installing and running 'naked' hybris platform","type":"post"},{"content":" How to setup new client # You need to be pensieve admin to do this. You will have to login as service user (non-host account) and su to root.\ncreate new Linux user on pensieve setup gitolite: git clone \u0026lt;git://github.com/sitaramc/gitolite\u0026gt; mkdir bin; export PATH=$PATH:~/bin gitolite/install -ln add own public key to gitolite to get access to gilotile-admin repo (note the naming restrictions!!) gitolite setup -pk miro.pub get public key for the client account admin and add it (there can be multiple admins) clone the gitolite-admin repo from workstation whose pub key was added git clone \u0026lt;client@pensieve.thinkwrap\u0026gt;.[com:gitolite-admin.git](http://comgitolite-admin.git/) add the key to the repo cd gitolite-admin cp ~/mykey.pub keydir vim conf/gitolite conf add the newly added account admit to repos, create new repos if required All gitolite installs are independent so modification in one hosting user have zero impact on others.\nProject administration # This assumes that you are account administrator - your public key has write (push) priviledge to gitolite-admin repository for your account.\nIf this is not true, please ask pensieve admin to add you to the account first - you must have access to gitolite-admin repo for your clients account\nClone the gitolite-admin repo:\ngit clone ACCOUNT@pensieve.thinkwrap.com:gitolite-admin.git Make sure you use proper account name for the URL.\nAll administration tasks are performed upon this gitolite-admin repo. By pushing the committed changes upstream, gitolite will \u0026ldquo;replay\u0026rdquo; and execute the changes.\nThere are three types of changes:\nadd new users/remove users create new repositories administer access of users to repositories How to add new repository # Go to gitolite-admin repository clone and edit the cong/gitolite.conf file\nAdd new repo name with access rights - example:\n$ cat gitolite-admin/conf/gitolite.conf repo gitolite-admin RW+ = miro RW+ = alter repo tmsp-release RW+ = alter R = @all repo tmsp-dev RW+ = @all repo testing RW+ = @all Each block starting with \u0026ldquo;repo\u0026rdquo; defines new repository.\nAdd new block to file, e.g. foobar\n... PREVIOUS REPOS ... repo foobar RW+ = developer1 R = @all Commit and push.\nGitolite will create new repository (located at $HOSTING_USER_HOME/repositories/foobar.git), make it available for push ONLY to developer1, allow everybody (all defined developers with public keys) to pull.\nThe URL of the repo will be HOSTING_USER_NAME@pensieve.thinkwrap.com:foobar.git Note that there is no repositories (or .git) in the URL. The later is optional.\nHow to add new user to your project # Get the public key from the developer to be added Make sure the naming convention works: if the name of the user (comment at the end of the file) is dev123@noteboook, store it in file dev123.pub. Add it to gitolite-admin/keydir (or subdirectory if there is a name conflict) Perform local commit and push How to administer access rights for a repository # make sure all users are added to the hosting account (see above) edit and push the gitolite-admin/conf/gitolite.conf ","date":"August 6, 2012","externalUrl":null,"permalink":"/posts/2012-08-06-gitilite-admin/","section":"Posts","summary":"How to setup new client # You need to be pensieve admin to do this. You will have to login as service user (non-host account) and su to root.\ncreate new Linux user on pensieve setup gitolite: git clone \u003cgit://github.com/sitaramc/gitolite\u003e mkdir bin; export PATH=$PATH:~/bin gitolite/install -ln add own public key to gitolite to get access to gilotile-admin repo (note the naming restrictions!!) gitolite setup -pk miro.pub get public key for the client account admin and add it (there can be multiple admins) clone the gitolite-admin repo from workstation whose pub key was added git clone \u003cclient@pensieve.thinkwrap\u003e.[com:gitolite-admin.git](http://comgitolite-admin.git/) add the key to the repo cd gitolite-admin cp ~/mykey.pub keydir vim conf/gitolite conf add the newly added account admit to repos, create new repos if required All gitolite installs are independent so modification in one hosting user have zero impact on others.\n","title":"Gitolite Administration Guide","type":"post"},{"content":" General setup of code sharing host # The code sharing host (Pensieve) is dedicated Linux server in DMZ, accessible from external locations as well as from internal network (dual homed) - for the build server access.\nMain features # multiple users each user represent a client: e.g. users client1 Users are separated by Unix permissions: # access rights to /home/USER are 0700 - no access except the dedicated user only ThinkWrap has root access or sudo access the access via ssh for the user is blocked - the user client1 cannot log in using ssh and get shell, only use git to pull or push changes Inside each user, there are multiple projects. # These projects will have multiple repositiories and will follow the naming convention:\nPROJECT_BASE_NAME-DEV_NAME PROJECT_BASE_NAME-RELEASE or PROJECT_BASE_NAME-THINKWRAP The PROJECT_BASE_NAME-THINKWRAP is the \u0026ldquo;blessed\u0026rdquo; repository from Integration manager workflow.\nThe external developers will be pulling from this repo, merging on their local workstations and pushing their released changes to their respective repositories in CodeShare\nInside each user there is ACL layer (Gitolite) which allows read-only or read-write access to repository.\nOnly ThinkWrap integration managers will have write access (push) to blessed repositories.\nExternal developers will have push access only to their own external repository on CodeShare All external developers will have pull (read-only) access to blessed repository.\nDepending on project setup, external developers may or may not have pull access to each other repositories (for sharing code before it goes through integration).\nInternal counterpart for the code sharing\nPensieve and CodeServer # Internally, we will have per-project area on internal repositories host - CodeServer\nEach project code area will follow exactly same naming convention:\nPROJECT_BASE_NAME-DEV_NAME PROJECT_BASE_NAME (the RELEASE - internal \u0026ldquo;blessed\u0026rdquo; repository) These developer\u0026rsquo;s repositories are external repositories of the team members and BLESSED is integration repository which receives code from developers\nThere will be similar ACL layer as in CodeShare, with somehow relaxed protection rules (tradeoff security for practicality):\nall projects will be probably using same internal \u0026ldquo;hosting\u0026rdquo; user internal developers will be able to have read (pull) access to Depending on project needs / size / requirements, we can support wide variety of control over code release repository\nstrict model - developers push to their external repositories, only team lead / integration manager can push to RELEASE relaxed model: some or all developers can push directly to release repository, IM handles external code transfers \u0026ldquo;minimized\u0026rdquo; model - there is only RELEASE repository on CodeServer and developers push directly to it (aka Subversion model). Team lead or IM is responsible to handle code transitions between Pensieve and CodeServer\nAll this access magic is possible because of the combination of the SSH and Gitolite (see http://sitaramc.github.com/gitolite/master-toc.html)\nHow Gitolite works # Everything is described in the manual, MAKE SURE you read these parts:\nhttp://sitaramc.github.com/gitolite/ssh.html http://sitaramc.github.com/gitolite/glssh.html - how it uses SSH http://sitaramc.github.com/gitolite/auth.html Gitolite provide access to repositories using single \u0026ldquo;hosting user\u0026rdquo; - this is the only Unix user that actually exists. In documentation, this hosting user is called git.\nIn our setup, this hosting user is customer user - e.g. client1. Consequently, there are many hosting users.\nFor each hosting user, we will have separate Gitolite configuration - it is very litlle overhead, all that Gitolite is bunch of Perl scripts two data directories and one small administration Git repository.\nSo there will be separate Gitolite setup for client1, where user \u0026lsquo;client1\u0026rsquo; will play the role of \u0026lsquo;git user\u0026rsquo;, separate and completely independent Gitolite setup for client2, where unix user \u0026lsquo;client2\u0026rsquo; will play the role \u0026lsquo;git user\u0026rsquo; etc etc. This can be easily scaled up to using separate hosts for customers if required.\nHow external developers access CodeShare # The only access mode is using the public key and SSH. We do not support\nlogging in using password https access All developers (including the Integration manager) are \u0026ldquo;virtual\u0026rdquo; identities. All will have to provide their public keys and the account admin (the person setting up Gitolite for the account, e.g. client1) will be responsible to\nadd these keys to account\u0026rsquo;s gitolite database create empty repositories for users set up access rights (read / write) for the repositories The Integration Manager can be the same person managing the account but it does not have to be. It is easy to allow multiple developers with write access to blessed repositories. Unlike the identity of the account admin (which is determined when Gitolite is set up for the account), these users can be added or removed at any time.\nThe setup of Gitolite is described here: http://sitaramc.github.com/gitolite/qi.html - it described \u0026ldquo;single account\u0026rdquo; hosting.\nTo make sure that everybody understands how does this translate to our situation, here is detailed step-by-step walkthrough to both setting up one user account and simulation of the development .\nSecurity and packability - Sidenote # The only way how to use Git is ssh with public key and we will not provide shell access, only git access. This makes sure that nobody from external developers can log into CodeShare and poke around in the repositories he/she does not have access to or even trying to gain root access or access othe accounts.\nKeeping very long password and rotating it can further increase security. For really paranoid customers, we can disable login shell access in /etc/passwd, but this will cause additional work the system administrator to make sure file ownership and permission are correct (when using root access).\nDetailed walkthrough of setup # This guide is using \u0026ldquo;temporary\u0026rdquo; VM named jenkins0 (the playground for build server) playing the role of CodeShare and shows all steps for setting up Gitolite on Jenkins0 for user client1.\nMain reason for this detailed log is to allow somebody else administer it and help my memory after the vacation !\nOn CodeShare # I have created users:\nclient1 client2 client3 This setup describes process for client1 and can be repeated for any other.\nStep one - setup Gitolite # Gitolite is distributred as Git repo, so we clone into home directory of hosting user (==client1)\n[client1@jenkins0 ~]$ pwd /home/client1 [client1@jenkins0 ~]$ git clone git://github.com/sitaramc/gitolite Cloning into gitolite... remote: Counting objects: 8267, done. remote: Compressing objects: 100% (2829/2829), done. remote: Total 8267 (delta 5682), reused 7848 (delta 5318) Receiving objects: 100% (8267/8267), 2.52 MiB | 1.12 MiB/s, done. Resolving deltas: 100% (5682/5682), done. It creates directory \u0026lsquo;~/gitolite\u0026rsquo; which contains few scripts\n[client1@jenkins0 ~]$ ll total 16 drwxr-xr-x 6 client1 client1 4096 Jun 17 16:38 gitolite -rw-r--r-- 1 client1 client1 393 Jun 17 12:02 luke.pub -rw-r--r-- 1 client1 client1 401 Jun 13 16:07 miro-radegast.pub drwxrwxr-x 5 client1 client1 4096 Jun 17 12:09 projects Pre-requisites for next step are:\nexisting ~/bin directory this directory as part of PATH Create bin directory # [client1@jenkins0 ~]$ mkdir ~/bin [client1@jenkins0 ~]$ export PATH=$PATH:~/bin [client1@jenkins0 ~]$ echo $PATH /usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/client1/bin:/home/client1/bin [client1@jenkins0 ~]$ Install it: # The install just creates symlink in ~/bin\n[client1@jenkins0 ~]$ gitolite/install -ln [client1@jenkins0 ~]$ ll ~/bin/ total 0 lrwxrwxrwx 1 client1 client1 35 Jun 17 16:40 gitolite -\u0026gt; /home/client1/gitolite/src/gitolite Next part is to setup Gitolite admin account.\nWe need a public key of the person that will be admininistering this hosting account.\nIt must satisfy few requirements:\nit must be in file USERNAME.pub, where USERNAME is actually username on admin\u0026rsquo;s system (which is stored in public key file) it MUST NOT be already in ~/.ssh/authorized_keys As we have freshly created the user \u0026lsquo;client1\u0026rsquo;, the ~/.ssh/authorized_keys is empty\nI have already copied my public key to jenkins0 - it is there as file \u0026lsquo;miro.pub\u0026rsquo;\nInside this file, there is username@hostname - it is important that you name the file properly (I found out the hard way)\nssh-rsa AAAAB3NzaC..... DELETED .... d9jajwIsLnJjw== miro``@Radegast``.local\nAdd private key: # [client1@jenkins0 ~]$ gitolite setup -pk miro.pub Initialized empty Git repository in /home/client1/repositories/gitolite-admin.git/ Initialized empty Git repository in /home/client1/repositories/testing.git/ [client1@jenkins0 ~]$ This created two Git repositories: gitolite-admin (which will be used for all administration) and test one.\nIt also adds user \u0026lsquo;miro\u0026rsquo; as admin of the gitolite with write access (push) to gitolite-admin repo\nUnder the hood:\nit adds public key of user \u0026lsquo;miro\u0026rsquo; to authorized_keys, but forces all communication using \u0026ldquo;command \u0026hellip;.\u0026rdquo; syntax (check the ssh documentation for details). This command causes that whenever user with this public key logs in, instead of getting shell access, gitolite intercepts and executes commands on its behalf. The setup also adds special hooks to gitolite-admin repository that help enforce access and trigger additional action after pushing changes. All this had to be done on jenkins0 (the CodeShare host)\nOn Client # On workstation from which the public key originated, I will need to clone the gitolite-admin repo:\nI am in the temp working directory \u0026lsquo;gitolite-on-jenkins0\u0026rsquo;, and \u0026lsquo;gs\u0026rsquo; is an alias for \u0026lsquo;git status\u0026rsquo;\ngitolite-on-jenkins0 $ git clone client1@192.168.16.144:gitolite-admin.git Cloning into \u0026#39;gitolite-admin\u0026#39;... remote: Counting objects: 6, done. remote: Compressing objects: 100% (4/4), done. remote: Total 6 (delta 0), reused 0 (delta 0) Receiving objects: 100% (6/6), done. Please note that I have used url \u0026lsquo;client1@hostname\u0026rsquo; format - not \u0026lsquo;miro@hostname\u0026rsquo;. We always connect using host identity.\nHere is what happens under the hood:\nclient tries to connect to hostnama as user \u0026lsquo;client1\u0026rsquo; and sends the default public key (from ~/.ssh/id_rsa.pub) This is the same key we set up on hostname ssh finds the key in authorized_keys and because there is command clause, hands over control to gitolite gitolite retrieves the name of the \u0026ldquo;virtual user\u0026rdquo; (miro), checks ACL list and allows / disallows the action The cloned repository has two areas:\nkeydir/ directory gitolite config files To add user for the hosting account, all you need to do is to copy properly named public key file under keydir/, add it and push the change.\nHere I have added tkuser@luke.pub (note that this naming is OK - see Gitolite docs for details).\nThe other file I am adding is from third VM and has weird name. I wanted to test the third format with two @ signs but get to it. Ignore this file.\nAfter copying the files, we add them in git, commit locally and push\ngitolite-admin $ gs # On branch master # Untracked files: # (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to include in what will be committed) # # keydir/miro.adamy+client3-dev-vf-osx@gmail.com@client3-dev-vf.pub # keydir/tkuser@luke.pub nothing added to commit but untracked files present (use \u0026#34;git add\u0026#34; to track) gitolite-admin $ git add keydir/ gitolite-admin $ gs # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # new file: keydir/miro.adamy+client3-dev-vf-osx@gmail.com@client3-dev-vf.pub # new file: keydir/tkuser@luke.pub # gitolite-admin $ git commit -m\u0026#34;Added 2 users\u0026#34; [master 18caa3d] Added 2 users 2 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 keydir/miro.adamy+client3-dev-vf-osx@gmail.com@client3-dev-vf.pub create mode 100644 keydir/tkuser@luke.pub Next step will be editing gitolite.conf # gitolite-admin $ vi conf/gitolite.conf gitolite-admin $ cat conf/gitolite.conf repo gitolite-admin RW+ = miro repo testing RW+ = @all repo projectOne projectTwo RW+ = tkuser RW+ = miro repo projectOne-Blessed R = tkuser RW+ = miro I will create two repositories for project named unimaginatively \u0026lsquo;projectOne\u0026rsquo;.\nThe projectOne repository (yes, I know this is not according naming convention - there should have been two repos named projectOne-tkuser, and projectOne-SomeOther developer. I will be cheating a bit and use \u0026ldquo;projectOne\u0026rdquo; as developer repository shared by two developers: tkuser@luke, and miro@radegast.\nUser miro@radegast will be wearing second hat as integration manager and will also have access to \u0026ldquo;blessed\u0026rdquo; repository named \u0026ldquo;projectOne-Blessed\u0026rdquo;.\nOK, this is also not according naming convention - which I have created AFTER this exercise.\nPlease do what I say to do, not what I do :-D\nThe syntax is documented in Gitolite, but here is the idea: but just naming the repositories, they will be created when we push gitolite-admin repo.\ngitolite-admin $ gs # On branch master # Your branch is ahead of \u0026#39;origin/master\u0026#39; by 1 commit. # # Changes not staged for commit: # (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) # (use \u0026#34;git checkout -- \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) # # modified: conf/gitolite.conf # no changes added to commit (use \u0026#34;git add\u0026#34; and/or \u0026#34;git commit -a\u0026#34;) gitolite-admin $ git add conf/gitolite.conf gitolite-admin $ git commit -m\u0026#34;Some repos\u0026#34; [master 35789bb] Some repos 1 files changed, 10 insertions(+), 0 deletions(-) When we push, lost of magic happens on the other end:\ngitolite-admin $ git push Counting objects: 13, done. Delta compression using up to 8 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (9/9), 1.46 KiB, done. Total 9 (delta 0), reused 0 (delta 0) remote: Initialized empty Git repository in /home/client1/repositories/projectOne.git/ remote: Initialized empty Git repository in /home/client1/repositories/projectOne-Blessed.git/ remote: Initialized empty Git repository in /home/client1/repositories/projectTwo.git/ To client1@192.168.16.144:gitolite-admin.git ca335c9..35789bb master -\u0026gt; master Also, worth noticing that miro.pub found its way into keydir - even if it was never added (the setup action copied it there).\ngitolite-admin $ ll keydir/ total 24 -rw-r--r-- 1 miro staff 418B 17 Jun 17:04 miro.adamy+client3-dev-vf-osx@gmail.com@client3-dev-vf.pub -rw-r--r-- 1 miro staff 401B 17 Jun 16:54 miro.pub -rw-r--r-- 1 miro staff 393B 17 Jun 17:01 tkuser@luke.pub Time to simulate some development. # I am still on Macbook, wearing my \u0026ldquo;developer\u0026rdquo; hat, go to directory where I work with client1 project and clone: (the directory is empty as we are just starting):\nclient1 $ pwd /Users/miro/Projects/Thinkwrap/Infrastructure/git-repos/client1 client1 $ ll client1 $ git clone client1@192.168.16.144:projectOne Cloning into \u0026#39;projectOne\u0026#39;... warning: You appear to have cloned an empty repository. Again, I used \u0026lsquo;client1@hostname\u0026rsquo; to connect.\nNote that the url does contain just repository name, while on server side the repos are stored in folder \u0026lsquo;repositories\u0026rsquo; and the directory is named \u0026lsquo;projectOne.git\u0026rsquo;. This is OK.\nI will also clone the blessed repository (now wearing my Integration manager hat):\nclient1 $ git clone client1@192.168.16.144:projectOne-Blessed Cloning into \u0026#39;projectOne-Blessed\u0026#39;... warning: You appear to have cloned an empty repository. client1 $ ll total 0 drwxr-xr-x 3 miro staff 102B 17 Jun 17:12 projectOne drwxr-xr-x 3 miro staff 102B 17 Jun 17:12 projectOne-Blessed Lets set up some content for the team to work on:\nI work in blessed - create 2 files, commit locally and push\nclient1 $ cd projectOne-Blessed/ projectOne-Blessed $ ll projectOne-Blessed $ ll ~/bin \u0026gt;bin-dir.txt projectOne-Blessed $ ll .. \u0026gt;this-dir.txt projectOne-Blessed $ gs # On branch master # # Initial commit # # Untracked files: # (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to include in what will be committed) # # bin-dir.txt # this-dir.txt nothing added to commit but untracked files present (use \u0026#34;git add\u0026#34; to track) projectOne-Blessed $ git add . projectOne-Blessed $ git commit -m\u0026#34;2 files\u0026#34; [master (root-commit) 4ecde6e] 2 files 2 files changed, 45 insertions(+), 0 deletions(-) create mode 100644 bin-dir.txt create mode 100644 this-dir.txt For the first push, you MUST specify the upstream repo and branch. Here is what happens if you do not:\nprojectOne-Blessed $ git push No refs in common and none specified; doing nothing. Perhaps you should specify a branch such as \u0026#39;master\u0026#39;. fatal: The remote end hung up unexpectedly error: failed to push some refs to \u0026#39;client1@192.168.16.144:projectOne-Blessed\u0026#39; OK then, I will push to origin (this is where I got the blessed repo from) and push the only branch - master\nprojectOne-Blessed $ git push origin master Counting objects: 4, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (4/4), 1.21 KiB, done. Total 4 (delta 0), reused 0 (delta 0) To client1@192.168.16.144:projectOne-Blessed * [new branch] master -\u0026gt; master Now it works.\nSecond developer # Now, second developer joined project. I will simulate him from Luke. His name is tkuser and his public key was already added to gitolite-admin\nI ssh to Luke - checkout the ProjectOne, connect upstream ProjectOne-blessed, add some files / modify some\n[tkuser@LUKE temp]$ git clone client1@192.168.16.144:projectOne Cloning into projectOne... warning: You appear to have cloned an empty repository. [tkuser@LUKE temp]$ cd projectOne/ [tkuser@LUKE projectOne]$ ll total 0 [tkuser@LUKE projectOne]$ ll ~ \u0026gt;my-home.txt [tkuser@LUKE projectOne]$ git add . [tkuser@LUKE projectOne]$ git commit -m \u0026#34;tkuser started\u0026#34; [master (root-commit) ac41962] tkuser started Committer: Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt; Your name and email address were configured automatically based on your username and hostname. Please check that they are accurate. You can suppress this message by setting them explicitly: git config --global user.name \u0026#34;Your Name\u0026#34; git config --global user.email you@example.com After doing this, you may fix the identity used for this commit with: git commit --amend --reset-author 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 my-home.txt From first commit (as there was never any development from Luke, I just installed Git there today), we get message that Git has trouble determining committer info and is using Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt;\nWe can fix this easily:\n[tkuser@LUKE projectOne]$ git config --global user.name \u0026#34;ThinkWrap User\u0026#34; [tkuser@LUKE projectOne]$ git config --global user.email tkuser.luke@thinkwrap.net The next commit will be better\n[tkuser@LUKE projectOne]$ git commit -m \u0026#34;tkuser started\u0026#34; # On branch master nothing to commit (working directory clean) [tkuser@LUKE projectOne]$ git status # On branch master nothing to commit (working directory clean) [tkuser@LUKE projectOne]$ ll total 8 -rw-rw-r-- 1 tkuser tkuser 1040 Jun 17 17:17 my-home.txt [tkuser@LUKE projectOne]$ pwd /home/tkuser/temp/projectOne As we see, two commits to local repo have different indentities. I could fix that by ammending the commit, and I would in real project, but lets move on:\n[tkuser@LUKE projectOne]$ git log commit ac419625e9bef60a8bfb4f78c676eb25b7dc85b9 Author: Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt; Date: Sun Jun 17 17:18:41 2012 -0400 tkuser started OK, some more hard development:\n[tkuser@LUKE projectOne]$ vim my-home.txt [tkuser@LUKE projectOne]$ git status # On branch master # Changes not staged for commit: # (use \u0026#34;git add \u0026lt;file\u0026gt;...\u0026#34; to update what will be committed) # (use \u0026#34;git checkout -- \u0026lt;file\u0026gt;...\u0026#34; to discard changes in working directory) # # modified: my-home.txt # no changes added to commit (use \u0026#34;git add\u0026#34; and/or \u0026#34;git commit -a\u0026#34;) [tkuser@LUKE projectOne]$ git commit -a -m \u0026#34;tkuser second\u0026#34; [master a6cbdf9] tkuser second 1 files changed, 6 insertions(+), 0 deletions(-) [tkuser@LUKE projectOne]$ git log commit a6cbdf9b3459c91572741c9ca2f5272e761b120f Author: ThinkWrap User \u0026lt;tkuser.luke@thinkwrap.net\u0026gt; Date: Sun Jun 17 17:20:56 2012 -0400 tkuser second commit ac419625e9bef60a8bfb4f78c676eb25b7dc85b9 Author: Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt; Date: Sun Jun 17 17:18:41 2012 -0400 tkuser started Now we will share the code with the users on the CodeShare:\n[tkuser@LUKE projectOne]$ git push origin master Counting objects: 6, done. Delta compression using up to 8 threads. Compressing objects: 100% (4/4), done. Writing objects: 100% (6/6), 867 bytes, done. Total 6 (delta 1), reused 0 (delta 0) To client1@192.168.16.144:projectOne * [new branch] master -\u0026gt; master What we have forgotten to do was to integrate code coming from ThinkWrap and shared in blessed repo.\nLet\u0026rsquo;s hook up the blessed to my local repository on Luke:\n[tkuser@LUKE projectOne]$ git remote add blessed client1@192.168.16.144:projectOne-Blessed [tkuser@LUKE projectOne]$ git remote -v blessed client1@192.168.16.144:projectOne-Blessed (fetch) blessed client1@192.168.16.144:projectOne-Blessed (push) origin client1@192.168.16.144:projectOne (fetch) origin client1@192.168.16.144:projectOne (push) This is \u0026ldquo;read-only\u0026rdquo; link even if it does not say so. We can now fetch the changes from blessed (I could have named it anything, it is just name).\n[tkuser@LUKE projectOne]$ git fetch blessed master warning: no common commits remote: Counting objects: 4, done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (4/4), done. From 192.168.16.144:projectOne-Blessed * branch master -\u0026gt; FETCH_HEAD This would be ideal situation if I want just to see what is going on, without impacting my local master.\nMore practical would be to merge the changes into my master, which is what pull does. Again, for first time I must be explicit what do I want to pull - here is what happens if I am not:\n[tkuser@LUKE projectOne]$ git pull blessed From 192.168.16.144:projectOne-Blessed * [new branch] master -\u0026gt; blessed/master You asked to pull from the remote \u0026#39;blessed\u0026#39;, but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line. OK, we want master:\n[tkuser@LUKE projectOne]$ git pull blessed master From 192.168.16.144:projectOne-Blessed * branch master -\u0026gt; FETCH_HEAD Merge made by recursive. bin-dir.txt | 42 ++++++++++++++++++++++++++++++++++++++++++ this-dir.txt | 3 +++ 2 files changed, 45 insertions(+), 0 deletions(-) create mode 100644 bin-dir.txt create mode 100644 this-dir.txt [tkuser@LUKE projectOne]$ gs ESP Ghostscript 815.02 (2006-04-19) Copyright (C) 2004 artofcode LLC, Benicia, CA. All rights reserved. This software comes with NO WARRANTY: see the file PUBLIC for details. GS\u0026gt; Eventually, I will get annoyed by GhostScript and kill it by defining my favorite alias:\n[tkuser@LUKE projectOne]$ alias gs=\u0026#39;git status\u0026#39; [tkuser@LUKE projectOne]$ gs # On branch master # Your branch is ahead of \u0026#39;origin/master\u0026#39; by 2 commits. # nothing to commit (working directory clean) So we are fine. All is merged, but only locally. Git indicates we need to push to origin.\nI have all files:\n[tkuser@LUKE projectOne]$ ll total 24 -rw-rw-r-- 1 tkuser tkuser 2704 Jun 17 17:24 bin-dir.txt -rw-rw-r-- 1 tkuser tkuser 1070 Jun 17 17:20 my-home.txt -rw-rw-r-- 1 tkuser tkuser 130 Jun 17 17:24 this-dir.txt Let\u0026rsquo;s push (now there is no need to say \u0026lsquo;master\u0026rsquo;):\n[tkuser@LUKE projectOne]$ git push origin Counting objects: 7, done. Delta compression using up to 8 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 1.48 KiB, done. Total 6 (delta 1), reused 0 (delta 0) To client1@192.168.16.144:projectOne a6cbdf9..5d8d73b master -\u0026gt; master What would happen if I wanted to short circuit the wait for integration manager and see my changes published right away in blessed repo ? Let\u0026rsquo;s try of Gitolite access control works:\n[tkuser@LUKE projectOne]$ git push blessed FATAL: W any projectOne-Blessed tkuser DENIED by fallthru (or you mis-spelled the reponame) fatal: The remote end hung up unexpectedly [tkuser@LUKE projectOne]$ cd .. As it looks like, it does :-D\nI will not give up - in addition to link the blessed repo from my projectOne, I will try to clone it locally (which I can do as I have read access and push it back:\n[tkuser@LUKE projectOne]$ cd .. [tkuser@LUKE temp]$ git clone client1@192.168.16.144:projectOne-Blessed Cloning into projectOne-Blessed... remote: Counting objects: 4, done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 0), reused 0 (delta 0) Receiving objects: 100% (4/4), done. OK, let\u0026rsquo;s hack it:\n[tkuser@LUKE temp]$ cd projectOne-Blessed/ [tkuser@LUKE projectOne-Blessed]$ ll total 16 -rw-rw-r-- 1 tkuser tkuser 2704 Jun 17 17:31 bin-dir.txt -rw-rw-r-- 1 tkuser tkuser 130 Jun 17 17:31 this-dir.txt [tkuser@LUKE projectOne-Blessed]$ vim bin-dir.txt [tkuser@LUKE projectOne-Blessed]$ git add . [tkuser@LUKE projectOne-Blessed]$ gs # On branch master # Changes to be committed: # (use \u0026#34;git reset HEAD \u0026lt;file\u0026gt;...\u0026#34; to unstage) # # modified: bin-dir.txt Local commit will work fine:\n[tkuser@LUKE projectOne-Blessed]$ git commit -m\u0026#34;Changing Blessed\u0026#34; [master eefd800] Changing Blessed 1 files changed, 2 insertions(+), 1 deletions(-) [tkuser@LUKE projectOne-Blessed]$ gs # On branch master # Your branch is ahead of \u0026#39;origin/master\u0026#39; by 1 commit. # nothing to commit (working directory clean) But push will fail:\n[tkuser@LUKE projectOne-Blessed]$ git push origin FATAL: W any projectOne-Blessed tkuser DENIED by fallthru (or you mis-spelled the reponame) fatal: The remote end hung up unexpectedly Back to Macbook and put on my Integration Manager hat: # Int Manager on MBP - working with local clone of blessed repo\nprojectOne-Blessed $ hostname Radegast.local projectOne-Blessed $ pwd /Users/miro/Projects/Thinkwrap/Infrastructure/git-repos/client1/projectOne-Blessed projectOne-Blessed $ Integration manager has better tools so I use SourceTree from Atlassian to\nattach developer1 repository on CodeShare (the projectOne tkuser used), fetch the changes review them, merged developer1/master pushed to BLESSED Back on Luke, I am tkuser now: # [tkuser@LUKE projectOne]$ git pull blessed master From 192.168.16.144:projectOne-Blessed * branch master -\u0026gt; FETCH_HEAD Already up-to-date. OK, this may be surprising: how come that IM pushed changes to blessed and tkuser does not see them ?\nWhat happened here is that the merge in Blessed was fast forward to latest and the latest is already in projectOne rep (as it originated from there). So nothing really changed just few references were moved.\nWe can verify that we do have the latest commit by checking the sha1\n[tkuser@LUKE projectOne]$ git log commit 5d8d73b7f24307482edbfc4ca1328dabdfcf8353 Merge: a6cbdf9 4ecde6e Author: ThinkWrap User \u0026lt;tkuser.luke@thinkwrap.net\u0026gt; Date: Sun Jun 17 17:24:13 2012 -0400 Merge branch \u0026#39;master\u0026#39; of 192.168.16.144:projectOne-Blessed commit a6cbdf9b3459c91572741c9ca2f5272e761b120f Author: ThinkWrap User \u0026lt;tkuser.luke@thinkwrap.net\u0026gt; Date: Sun Jun 17 17:20:56 2012 -0400 tkuser second commit ac419625e9bef60a8bfb4f78c676eb25b7dc85b9 Author: Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt; Date: Sun Jun 17 17:18:41 2012 -0400 tkuser started commit 4ecde6eebd93448628c6475e12da380a962aecc9 Author: Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; Date: Sun Jun 17 17:15:04 2012 -0400 2 files Or we can even see the fancy ASCII-Artsy graph:\n[tkuser@LUKE projectOne]$ git log --graph * commit 5d8d73b7f24307482edbfc4ca1328dabdfcf8353 |\\ Merge: a6cbdf9 4ecde6e | | Author: ThinkWrap User \u0026lt;tkuser.luke@thinkwrap.net\u0026gt; | | Date: Sun Jun 17 17:24:13 2012 -0400 | | | | Merge branch \u0026#39;master\u0026#39; of 192.168.16.144:projectOne-Blessed | | | * commit 4ecde6eebd93448628c6475e12da380a962aecc9 | Author: Miro Adamy \u0026lt;miro.adamy@thinkwrap.com\u0026gt; | Date: Sun Jun 17 17:15:04 2012 -0400 | | 2 files | * commit a6cbdf9b3459c91572741c9ca2f5272e761b120f | Author: ThinkWrap User \u0026lt;tkuser.luke@thinkwrap.net\u0026gt; | Date: Sun Jun 17 17:20:56 2012 -0400 | | tkuser second | * commit ac419625e9bef60a8bfb4f78c676eb25b7dc85b9 Author: Thinknostic User \u0026lt;tkuser@LUKE.(none)\u0026gt; Date: Sun Jun 17 17:18:41 2012 -0400 tkuser started [tkuser@LUKE projectOne]$ Sharing external repo among developers # For the final part, lets create scenario that does not happen if every developer has his/her own external repo on CodeShare, but which will certainly happen in the setup where multiple developer push to same external repo - kinda centralized mode.\nI will start by add local change to projectOne repo on MBPro by Miro. Back on Macbook:\nprojectOne-Blessed $ cd ../projectOne projectOne $ ll total 24 -rw-r--r-- 1 miro staff 2.6K 17 Jun 17:47 bin-dir.txt -rw-r--r-- 1 miro staff 1.0K 17 Jun 17:47 my-home.txt -rw-r--r-- 1 miro staff 130B 17 Jun 17:47 this-dir.txt projectOne $ vim this-dir.txt projectOne $ git commit -a -m\u0026#34;local by Miro\u0026#34; [master c62dd90] local by Miro 1 files changed, 1 insertions(+), 1 deletions(-) projectOne $ git push Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 297 bytes, done. Total 3 (delta 2), reused 0 (delta 0) To client1@192.168.16.144:projectOne 5d8d73b..c62dd90 master -\u0026gt; master At the same time, tkuser on luke did also change something - starting from same starting code as miron on Radegast: attempt to push will this time end up with conflict\n[tkuser@LUKE projectOne]$ ll total 24 -rw-rw-r-- 1 tkuser tkuser 2704 Jun 17 17:24 bin-dir.txt -rw-rw-r-- 1 tkuser tkuser 1070 Jun 17 17:20 my-home.txt -rw-rw-r-- 1 tkuser tkuser 130 Jun 17 17:24 this-dir.txt [tkuser@LUKE projectOne]$ vim my-home.txt [tkuser@LUKE projectOne]$ git commit -a -m\u0026#34;Changing my home on Luke\u0026#34; [master deb5d23] Changing my home on Luke 1 files changed, 0 insertions(+), 1 deletions(-) Note that local commit is always OK, it will be the push that fails:\n[tkuser@LUKE projectOne]$ git push To client1@192.168.16.144:projectOne ! [rejected] master -\u0026gt; master (non-fast-forward) error: failed to push some refs to \u0026#39;client1@192.168.16.144:projectOne\u0026#39; To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. \u0026#39;git pull\u0026#39;) before pushing again. See the \u0026#39;Note about fast-forwards\u0026#39; section of \u0026#39;git push --help\u0026#39; for details. Git was nice enough to tell me what to do. Let\u0026rsquo;s pull:\n[tkuser@LUKE projectOne]$ git pull remote: Counting objects: 5, done. remote: Compressing objects: 100% (3/3), done. remote: Total 3 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From 192.168.16.144:projectOne 5d8d73b..c62dd90 master -\u0026gt; origin/master Merge made by recursive. this-dir.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Merge resulted in new commit - it was done right away as there were no conflicts. We can push again:\n[tkuser@LUKE projectOne]$ git push Counting objects: 8, done. Delta compression using up to 8 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 618 bytes, done. Total 5 (delta 2), reused 0 (delta 0) To client1@192.168.16.144:projectOne c62dd90..e031acf master -\u0026gt; master [tkuser@LUKE projectOne]$ Security and hackability # Last note is on security. The hacker\u0026rsquo;s soul in tkuser wants to see what else except projectOne is on CodeShare. Let\u0026rsquo;s log on.\nAttempt to bypass the security by logging on as hosting user # [tkuser@LUKE ~]$ ssh client1@192.168.16.144 hello tkuser, this is client1@jenkins0 running gitolite3 v3.03-34-ga171053 on git 1.7.7.1 R W projectOne R projectOne-Blessed R W projectTwo R W testing Connection to 192.168.16.144 closed. Bummer. Gitolite was nice enough to show all repos made available for the user, but rejected the login.\nTherefore: public key is the only supported way how to access CodeShare repo.\nFor admins and such who know the password the ssh is still there (unless we change it git-shell).\nI will prove this by logging in with different identity (to prevent my public key being sent) - I will use my public key I use for github:\nclient1 $ ssh -i ~/.ssh/github_rsa.pub client1@192.168.16.144 client1@192.168.16.144\u0026#39;s password: Last login: Sun Jun 17 14:38:57 2012 from 192.168.16.108 [client1@jenkins0 ~]$ In this case, it asks for password and logs me in\nAnd that is end of the walkthrough\n","date":"June 21, 2012","externalUrl":null,"permalink":"/posts/2012-06-21-gitolite-setup/","section":"Posts","summary":"General setup of code sharing host # The code sharing host (Pensieve) is dedicated Linux server in DMZ, accessible from external locations as well as from internal network (dual homed) - for the build server access.\nMain features # multiple users each user represent a client: e.g. users client1 Users are separated by Unix permissions: # access rights to /home/USER are 0700 - no access except the dedicated user only ThinkWrap has root access or sudo access the access via ssh for the user is blocked - the user client1 cannot log in using ssh and get shell, only use git to pull or push changes Inside each user, there are multiple projects. # These projects will have multiple repositiories and will follow the naming convention:\n","title":"Using Gitolite for code sharing setup","type":"post"},{"content":" tmutil # The tmutil - everything to know about Time machine backups. For example, why is the MBP backing up 4.3 GB \u0026hellip; again.\nLion only. See http://www.macgurulounge.com/see-which-files-time-machine-backed-up/ for Snow Leopard and before.\n547 tmutil 548 tmutil help 549 tmutil help listbackups 550 tmutil listbackups 551 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 552 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-171551/ 553 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ 554 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-130159/ 555 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 556 tmutil compare /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 here is why: # ~ $ tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-13 2012-05-27-130159/ 2012-05-27-131532/ ~ $ tmutil compare /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 ! 5.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashPlan/conf/service.model ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter ! 18.6K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist ! 7.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter/SubmitDiagInfo.domains ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences ! 713B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences/com.apple.TimeMachine.plist ! 503B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences/com.apple.applepushserviced.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop + 55.2K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop/Screen Shot 2012-05-27 at 1.36.29 PM.png ! 102.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop/.DS_Store ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Documents/Microsoft User Data/Office 2011 AutoRecovery - 15.8M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Documents/Microsoft User Data/Office 2011 AutoRecovery/PowerPoint Temp ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads - 271.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/Introduction To GIT.ppt - 1.0M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/egit1-0-110705134610-phpapp02.odp - 1.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-100618212852-phpapp01.zip - 719.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-1212761677968831-9.pdf - 2.7M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-presentation.pdf - 709.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitandeclipsejena-100617100628-phpapp02.ppt - 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitstartedwithgit-nhruby-090501133113-phpapp02 (1).pdf - 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitstartedwithgit-nhruby-090501133113-phpapp02.pdf - 645.7K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/introtogit-090518104200-phpapp02.pdf - 5.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/progit.en.pdf + 330.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads/ECKHART TOLLE - Moc pritomnÇho okamziku - audiokniha.1 + 122.2M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads/Eckhart Tolle - Stille spricht Hîrbuch ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/AddressBook ! 10B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/AddressBook/.database.lockN ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CalendarBar ! 2.3M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CalendarBar/GoogleCalendar.sqlite ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers ! 459B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/192.168.16.248.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGHome - home en0.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - 16.52.rdp ! 466B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - Bonjour.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - Rocket.rdp ! 455B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Chewbaca.rdp ! 454B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Chewbacca.rdp ! 452B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Igor.rdp ! 437B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/New Server.rdp ! 453B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/TW_ATG.rdp ! 461B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/XP Pro VM Luke.rdp ! 13.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CrashReporter/Intervals_5DE3241B-6882-529D-B8D6-404D684BE551.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/accounts/Evernote/miroadamy/promos ! 42B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/accounts/Evernote/miroadamy/promos/stats.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/skus ! 469B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/skus/www.evernote.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default ! 1.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Cookies ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Cookies-journal ! 1010.0K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Current Session ! 906.8K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Current Tabs ! 16.2M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/History Index 2012-05 ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage/http_mediacdn.disqus.com_0.localstorage ! 3.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage/https_www.icloud.com_0.localstorage ! 58.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Login Data ! 4.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Login Data-journal ! 2.8M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Network Action Predictor ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Network Action Predictor-journal ! 94.2K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Preferences ! 200.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Shortcuts ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Shortcuts-journal ! 8.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Sync Data/SyncData.sqlite3 ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Sync Data/SyncData.sqlite3-journal ! 400.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Top Sites ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Top Sites-journal ! 3.4K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/TransportSecurity ! 511.9K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Visited Links ! 1.1M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Web Data ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Web Data-journal ! 12.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Local State ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Path Finder/Settings/Data Store ! 1.2M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Path Finder/Settings/Data Store/directoryAttributes.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/Accounts/miro.adamy@gmail.com ! 27.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/Accounts/miro.adamy@gmail.com/avatar.tiff ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/LocalDrafts ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb ! 1023.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb/messages.db-wal ! 899B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb/syncdates.plist ! 775.7K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/email.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb ! 1.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb/messages.db-wal ! 4.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FAll%20Mail ! 442B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FAll%20Mail/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FDrafts ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FDrafts/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FImportant ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FImportant/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSent%20Mail ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSent%20Mail/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSpam ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSpam/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FTrash ! 442B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FTrash/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/INBOX ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/INBOX/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/spam-ish ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/spam-ish/uids ! 68.6M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/contents.index ! 11.4M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/from.index ! 11.8M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/recipient.index ! 11.6M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/subject.index ! 397.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/contents-cache.db/data.tch ! 127.4M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/conversations-cache.db/data.tch ! 310.6M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages-cache.db/data.tch ! 54.3M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages.db ! 1.2M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages.db-wal ! 125.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/preview-cache.db/data.tch ! 51.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/search-metadata.db/data.tch ! 2.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb ! 1023.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb/messages.db-wal ! 834B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/tmp ! 6.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/uistate.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives - 0B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives/com.google.GoogleDrive ! 0B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives/com.google.Chrome ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Stats ! 181B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Stats/Keystone.stats ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Keychains ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences ! 2.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/.GlobalPreferences.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost ! 1.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/.GlobalPreferences.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 434B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.CrashReporter.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 526B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.HIToolbox.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 190B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.SubmitDiagInfo.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 1.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.loginwindow.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM + 0B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM/media.miamiherald.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM/www.wimp.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys + 91B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys/#media.miamiherald.com ! 2.6K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys/settings.sol ! 124B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.ATS.plist ! 623B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.PreferenceSync.plist ! 443B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.internetconfigpriv.plist ! 446B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.loginwindow.plist ! 24.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.recentitems.plist ! 1.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.cleancutcode.CalendarBar.plist ! 76.7K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.cocoatech.PathFinder.plist ! 886B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.google.Keystone.Agent.plist ! 6.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.Powerpoint.plist ! 254B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.error_reporting.plist ! 258.8K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.office.plist ! 18.9K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.sparrowmailapp.sparrow.plist ! 17.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.torusknot.SourceTree.plist ! 12.9K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/de.jinx.JollysFastVNC.Pro.plist ! 2.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/net.sf.cord.plist ! 2.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/org.vim.MacVim.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari ! 225.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/History.plist ! 14.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LastSession.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LocalStorage ! 10.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LocalStorage/safari-extension_com.divx.wpa-kzyj7hj34p_0.localstorage ! 1.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/TopSites.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Spelling ! 3.0K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Spelling/dynamic-text.dat ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/SyncedPreferences ! 993B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/SyncedPreferences/com.apple.syncedpreferences.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git + 5.8M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Git-2a.pptx + 271.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Introduction To GIT.ppt + 1.0M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/egit1-0-110705134610-phpapp02.odp + 1.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-100618212852-phpapp01.zip + 719.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-1212761677968831-9.pdf + 2.7M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-presentation.pdf + 709.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitandeclipsejena-100617100628-phpapp02.ppt + 2.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitintro-110722021214-phpapp02.ppt + 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitstartedwithgit-nhruby-090501133113-phpapp02 (1).pdf + 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitstartedwithgit-nhruby-090501133113-phpapp02.pdf + 645.7K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/introtogit-090518104200-phpapp02.pdf + 5.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/progit.en.pdf ! 10.3M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Git-1.pptx ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/etc/cups/certs ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/tmp ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db ! 1.1K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/.TimeMachine.Results.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC + 19.0K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC/app.com.microsoft.error_reporting.playlist ! 21.2K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC/app.com.microsoft.Powerpoint.playlist ! 20B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/SystemEntropyCache ! 616B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/com.apple.TimeMachine.SnapshotDates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls ! 3.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/AC99EBF7D89822D3A424E7768D107BCD60A9A0F5.pem ! 3.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/FE2FDB1DABD01758E9B204075DBB026D1D3E6B3B.pem ! 320.9K (size) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/crlcache.db ! 13.3K (size) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/ocspcache.db ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/vm ------------------------------------- Added: 475.1M Removed: 30.1M Changed: 1.2G Diff # Which libs are in that Ant81 and not in Ant71 ?\n[tkuser@jenkins2 opt]$ diff -q apache-ant-1.7.1/lib apache-ant-1.8.2/lib | grep jar | more Files apache-ant-1.7.1/lib/ant-antlr.jar and apache-ant-1.8.2/lib/ant-antlr.jar differ Files apache-ant-1.7.1/lib/ant-apache-bcel.jar and apache-ant-1.8.2/lib/ant-apache-bcel.jar differ Files apache-ant-1.7.1/lib/ant-apache-bsf.jar and apache-ant-1.8.2/lib/ant-apache-bsf.jar differ Files apache-ant-1.7.1/lib/ant-apache-log4j.jar and apache-ant-1.8.2/lib/ant-apache-log4j.jar differ Files apache-ant-1.7.1/lib/ant-apache-oro.jar and apache-ant-1.8.2/lib/ant-apache-oro.jar differ Files apache-ant-1.7.1/lib/ant-apache-regexp.jar and apache-ant-1.8.2/lib/ant-apache-regexp.jar differ Files apache-ant-1.7.1/lib/ant-apache-resolver.jar and apache-ant-1.8.2/lib/ant-apache-resolver.jar differ Only in apache-ant-1.8.2/lib: ant-apache-xalan2.jar Files apache-ant-1.7.1/lib/ant-commons-logging.jar and apache-ant-1.8.2/lib/ant-commons-logging.jar differ Files apache-ant-1.7.1/lib/ant-commons-net.jar and apache-ant-1.8.2/lib/ant-commons-net.jar differ Files apache-ant-1.7.1/lib/ant-jai.jar and apache-ant-1.8.2/lib/ant-jai.jar differ Files apache-ant-1.7.1/lib/ant.jar and apache-ant-1.8.2/lib/ant.jar differ Files apache-ant-1.7.1/lib/ant-javamail.jar and apache-ant-1.8.2/lib/ant-javamail.jar differ Files apache-ant-1.7.1/lib/ant-jdepend.jar and apache-ant-1.8.2/lib/ant-jdepend.jar differ Files apache-ant-1.7.1/lib/ant-jmf.jar and apache-ant-1.8.2/lib/ant-jmf.jar differ Files apache-ant-1.7.1/lib/ant-jsch.jar and apache-ant-1.8.2/lib/ant-jsch.jar differ Only in apache-ant-1.8.2/lib: ant-junit4.jar Files apache-ant-1.7.1/lib/ant-junit.jar and apache-ant-1.8.2/lib/ant-junit.jar differ Files apache-ant-1.7.1/lib/ant-launcher.jar and apache-ant-1.8.2/lib/ant-launcher.jar differ Files apache-ant-1.7.1/lib/ant-netrexx.jar and apache-ant-1.8.2/lib/ant-netrexx.jar differ Only in apache-ant-1.7.1/lib: ant-nodeps.jar Only in apache-ant-1.7.1/lib: ant-starteam.jar Only in apache-ant-1.7.1/lib: ant-stylebook.jar Files apache-ant-1.7.1/lib/ant-swing.jar and apache-ant-1.8.2/lib/ant-swing.jar differ Files apache-ant-1.7.1/lib/ant-testutil.jar and apache-ant-1.8.2/lib/ant-testutil.jar differ Only in apache-ant-1.7.1/lib: ant-trax.jar Only in apache-ant-1.7.1/lib: ant-weblogic.jar Only in apache-ant-1.7.1/lib: jsch-0.1.44.jar Only in apache-ant-1.7.1/lib: xercesImpl.jar Only in apache-ant-1.7.1/lib: xml-apis.jar ","date":"May 29, 2012","externalUrl":null,"permalink":"/posts/2012-05-29-admin-tool-goodies/","section":"Posts","summary":"tmutil # The tmutil - everything to know about Time machine backups. For example, why is the MBP backing up 4.3 GB … again.\nLion only. See http://www.macgurulounge.com/see-which-files-time-machine-backed-up/ for Snow Leopard and before.\n547 tmutil 548 tmutil help 549 tmutil help listbackups 550 tmutil listbackups 551 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 552 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-171551/ 553 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ 554 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-130159/ 555 tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 556 tmutil compare /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 here is why: # ~ $ tmutil uniquesize /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-13 2012-05-27-130159/ 2012-05-27-131532/ ~ $ tmutil compare /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/ /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449 ! 5.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashPlan/conf/service.model ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter ! 18.6K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter/DiagnosticMessagesHistory.plist ! 7.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Application Support/CrashReporter/SubmitDiagInfo.domains ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences ! 713B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences/com.apple.TimeMachine.plist ! 503B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Library/Preferences/com.apple.applepushserviced.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop + 55.2K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop/Screen Shot 2012-05-27 at 1.36.29 PM.png ! 102.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Desktop/.DS_Store ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Documents/Microsoft User Data/Office 2011 AutoRecovery - 15.8M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Documents/Microsoft User Data/Office 2011 AutoRecovery/PowerPoint Temp ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads - 271.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/Introduction To GIT.ppt - 1.0M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/egit1-0-110705134610-phpapp02.odp - 1.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-100618212852-phpapp01.zip - 719.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-1212761677968831-9.pdf - 2.7M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/git-presentation.pdf - 709.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitandeclipsejena-100617100628-phpapp02.ppt - 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitstartedwithgit-nhruby-090501133113-phpapp02 (1).pdf - 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/gitstartedwithgit-nhruby-090501133113-phpapp02.pdf - 645.7K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/introtogit-090518104200-phpapp02.pdf - 5.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Downloads/progit.en.pdf + 330.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads/ECKHART TOLLE - Moc pritomnÇho okamziku - audiokniha.1 + 122.2M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Downloads/Eckhart Tolle - Stille spricht Hîrbuch ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/AddressBook ! 10B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/AddressBook/.database.lockN ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CalendarBar ! 2.3M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CalendarBar/GoogleCalendar.sqlite ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers ! 459B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/192.168.16.248.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGHome - home en0.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - 16.52.rdp ! 466B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - Bonjour.rdp ! 462B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/ATGMobile - Rocket.rdp ! 455B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Chewbaca.rdp ! 454B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Chewbacca.rdp ! 452B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/Igor.rdp ! 437B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/New Server.rdp ! 453B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/TW_ATG.rdp ! 461B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CoRD/Servers/XP Pro VM Luke.rdp ! 13.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/CrashReporter/Intervals_5DE3241B-6882-529D-B8D6-404D684BE551.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/accounts/Evernote/miroadamy/promos ! 42B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/accounts/Evernote/miroadamy/promos/stats.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/skus ! 469B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Evernote/skus/www.evernote.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default ! 1.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Cookies ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Cookies-journal ! 1010.0K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Current Session ! 906.8K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Current Tabs ! 16.2M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/History Index 2012-05 ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage/http_mediacdn.disqus.com_0.localstorage ! 3.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Local Storage/https_www.icloud.com_0.localstorage ! 58.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Login Data ! 4.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Login Data-journal ! 2.8M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Network Action Predictor ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Network Action Predictor-journal ! 94.2K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Preferences ! 200.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Shortcuts ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Shortcuts-journal ! 8.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Sync Data/SyncData.sqlite3 ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Sync Data/SyncData.sqlite3-journal ! 400.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Top Sites ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Top Sites-journal ! 3.4K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/TransportSecurity ! 511.9K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Visited Links ! 1.1M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Web Data ! 16.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Default/Web Data-journal ! 12.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Google/Chrome/Local State ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Path Finder/Settings/Data Store ! 1.2M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Path Finder/Settings/Data Store/directoryAttributes.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/Accounts/miro.adamy@gmail.com ! 27.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/Accounts/miro.adamy@gmail.com/avatar.tiff ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/LocalDrafts ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb ! 1023.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb/messages.db-wal ! 899B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/camry2002ottawa@gmail.com.sparrowdb/syncdates.plist ! 775.7K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/email.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb ! 1.0M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb/messages.db-wal ! 4.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@gmail.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FAll%20Mail ! 442B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FAll%20Mail/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FDrafts ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FDrafts/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FImportant ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FImportant/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSent%20Mail ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSent%20Mail/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSpam ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FSpam/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FTrash ! 442B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/%5BGmail%5D%2FTrash/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/INBOX ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/INBOX/uids ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/spam-ish ! 440B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Cache/spam-ish/uids ! 68.6M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/contents.index ! 11.4M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/from.index ! 11.8M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/recipient.index ! 11.6M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/Indexes/subject.index ! 397.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/contents-cache.db/data.tch ! 127.4M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/conversations-cache.db/data.tch ! 310.6M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages-cache.db/data.tch ! 54.3M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages.db ! 1.2M (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/messages.db-wal ! 125.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/preview-cache.db/data.tch ! 51.7M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/search-metadata.db/data.tch ! 2.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/miro.adamy@thinkwrap.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb ! 1023.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb/messages.db-wal ! 834B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/radegast4@gmail.com.sparrowdb/syncdates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/tmp ! 6.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Application Support/Sparrow/uistate.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives - 0B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-131532/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives/com.google.GoogleDrive ! 0B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Actives/com.google.Chrome ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Stats ! 181B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Google/GoogleSoftwareUpdate/Stats/Keystone.stats ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Keychains ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences ! 2.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/.GlobalPreferences.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost ! 1.5K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/.GlobalPreferences.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 434B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.CrashReporter.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 526B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.HIToolbox.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 190B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.SubmitDiagInfo.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! 1.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/ByHost/com.apple.loginwindow.5DE3241B-6882-529D-B8D6-404D684BE551.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM + 0B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM/media.miamiherald.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/#SharedObjects/CA7U5XUM/www.wimp.com ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys + 91B /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys/#media.miamiherald.com ! 2.6K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/Macromedia/Flash Player/macromedia.com/support/flashplayer/sys/settings.sol ! 124B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.ATS.plist ! 623B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.PreferenceSync.plist ! 443B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.internetconfigpriv.plist ! 446B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.loginwindow.plist ! 24.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.apple.recentitems.plist ! 1.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.cleancutcode.CalendarBar.plist ! 76.7K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.cocoatech.PathFinder.plist ! 886B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.google.Keystone.Agent.plist ! 6.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.Powerpoint.plist ! 254B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.error_reporting.plist ! 258.8K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.microsoft.office.plist ! 18.9K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.sparrowmailapp.sparrow.plist ! 17.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/com.torusknot.SourceTree.plist ! 12.9K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/de.jinx.JollysFastVNC.Pro.plist ! 2.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/net.sf.cord.plist ! 2.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Preferences/org.vim.MacVim.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari ! 225.3K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/History.plist ! 14.4K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LastSession.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LocalStorage ! 10.0K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/LocalStorage/safari-extension_com.divx.wpa-kzyj7hj34p_0.localstorage ! 1.3K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Safari/TopSites.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Spelling ! 3.0K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/Spelling/dynamic-text.dat ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/SyncedPreferences ! 993B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Library/SyncedPreferences/com.apple.syncedpreferences.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git + 5.8M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Git-2a.pptx + 271.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Introduction To GIT.ppt + 1.0M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/egit1-0-110705134610-phpapp02.odp + 1.3M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-100618212852-phpapp01.zip + 719.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-1212761677968831-9.pdf + 2.7M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/git-presentation.pdf + 709.5K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitandeclipsejena-100617100628-phpapp02.ppt + 2.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitintro-110722021214-phpapp02.ppt + 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitstartedwithgit-nhruby-090501133113-phpapp02 (1).pdf + 885.9K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/gitstartedwithgit-nhruby-090501133113-phpapp02.pdf + 645.7K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/introtogit-090518104200-phpapp02.pdf + 5.4M /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/progit.en.pdf ! 10.3M (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/Users/miro/Projects/Training/Git/Git-1.pptx ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/etc/cups/certs ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/tmp ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db ! 1.1K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/.TimeMachine.Results.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC + 19.0K /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC/app.com.microsoft.error_reporting.playlist ! 21.2K (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/BootCaches/FCD06070-6268-466A-A3D6-C697CA300BAC/app.com.microsoft.Powerpoint.playlist ! 20B (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/SystemEntropyCache ! 616B (size, mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/com.apple.TimeMachine.SnapshotDates.plist ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls ! 3.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/AC99EBF7D89822D3A424E7768D107BCD60A9A0F5.pem ! 3.2K (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/FE2FDB1DABD01758E9B204075DBB026D1D3E6B3B.pem ! 320.9K (size) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/crlcache.db ! 13.3K (size) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/db/crls/ocspcache.db ! (mtime) /Volumes/Radegast2-TM/Backups.backupdb/Radegast/2012-05-27-162449/Macintosh HD/private/var/vm ------------------------------------- Added: 475.1M Removed: 30.1M Changed: 1.2G Diff # Which libs are in that Ant81 and not in Ant71 ?\n","title":"Admin tool goodies","type":"post"},{"content":"Being two weeks without \u0026ldquo;permanent computer home\u0026rdquo; and living among old Helios, MacMini, temp repair and Web was interesting experience. I certainly remember most of my Web passwords (again).\nGot my new MacBook Pro replacement yesterday. Pretty sweet upgrade: quad-core i7 @ 2.4, 8 GB RAM, 750 GB HDD 7200 RPM, Thunderbolt. Noticeably faster but also a bit louder - runs fans more often, maybe it is just while Spotlight does index everything ?\nIt came with Lion, so I am staying. I will not bother to do Java 5 - Cineplex is moving to ATG10, B2B will be ATG 10, so it is time to leave it behind.\nAfter some contemplation whether start from scratch I decided to restore from TimeMachine - there is no time now to twiddle with environment, however tempting it is. So I restored same semi-messy state as I left it 2 weeks ago. Restore was smooth, it did run for about 5 hours yesterday. Today, I briefly reviewed and removed some relicts from the disk, but did not go into too much effort to sort things out.\nWhat works (tested):\nFusion - upgraded to higher minor version, start of the VM is much shorter Flow, Cord, SourceTree, MacVim, PathFinder, IntelliJ (after I installed Java). all cloud services (CrashPlan, GoogleDrive, DropBox, Evernote, SugarSync, 1Password) Document tools - Curio, OmniGraffle, What does not work is bloody Office. It lost its serial number so I will need to find it, enter it and maybe spend time on line with Microsoft to resolve the issue. My distaste for everything Redmond cannot be any bigger\n","date":"May 13, 2012","externalUrl":null,"permalink":"/posts/2012-05-13-homelessness-over/","section":"Posts","summary":"Being two weeks without “permanent computer home” and living among old Helios, MacMini, temp repair and Web was interesting experience. I certainly remember most of my Web passwords (again).\nGot my new MacBook Pro replacement yesterday. Pretty sweet upgrade: quad-core i7 @ 2.4, 8 GB RAM, 750 GB HDD 7200 RPM, Thunderbolt. Noticeably faster but also a bit louder - runs fans more often, maybe it is just while Spotlight does index everything ?\n","title":"Homelessness is over, moved in","type":"post"},{"content":"After I created the ThinkWrap GitHub account and uploaded the public key, this key got somehow bound to GitHub identity \u0026lsquo;madamy\u0026rsquo;\nI had to add user madamy to my public GitHub repo - where I keep the dot-files - https://github.com/radegast/dotvim\nThis may be an issue for people that have their own private accounts - the key management is the key.\nThis article is useful:\nhttp://sealedabstract.com/code/github-ssh-with-multiple-identities-the-slightly-more-definitive-guide/ http://net.tutsplus.com/tutorials/tools-and-tips/how-to-work-with-github-and-multiple-accounts/ Alternative # Use https for forking , instead read/write ssh. No keys involved there\n","date":"April 15, 2012","externalUrl":null,"permalink":"/posts/2012-04-15-github/","section":"Posts","summary":"After I created the ThinkWrap GitHub account and uploaded the public key, this key got somehow bound to GitHub identity ‘madamy’\nI had to add user madamy to my public GitHub repo - where I keep the dot-files - https://github.com/radegast/dotvim\nThis may be an issue for people that have their own private accounts - the key management is the key.\nThis article is useful:\nhttp://sealedabstract.com/code/github-ssh-with-multiple-identities-the-slightly-more-definitive-guide/ http://net.tutsplus.com/tutorials/tools-and-tips/how-to-work-with-github-and-multiple-accounts/ Alternative # Use https for forking , instead read/write ssh. No keys involved there\n","title":"GitHub identity mixup","type":"post"},{"content":" Add this to .bashrc # export GIT_EDITOR=\u0026rsquo;/Applications/MacVim.app/Contents/MacOS/Vim -g -f '\nThe key is -f, without it git will abort because of empty commit message.\n","date":"April 9, 2012","externalUrl":null,"permalink":"/posts/2012-04-09-macvim-git/","section":"Posts","summary":"Add this to .bashrc # export GIT_EDITOR=’/Applications/MacVim.app/Contents/MacOS/Vim -g -f '\nThe key is -f, without it git will abort because of empty commit message.\n","title":"Using MacVim as git editor","type":"post"},{"content":"Out of the box Quick View (press Space in Finder) behaviour on unregistered files is not very useful: it shows huge Unix icon instead of content of file.\nThis is default for files like Makefile or build.gradle\nThis plugin makes it go away and show text file for all UTIs that are plain text: http://whomwah.github.com/qlstephen/\nInstallation:\nopen the DMG file copy QLStephen.qlgenerator to /Users/\u0026lt;\u0026lt;USERNAME\u0026gt;\u0026gt;/Library/QuickLook/QLStephen.qlgenerator That\u0026rsquo;s it.\nNow it looks like this:\n![](/images/image2012-4-8 1_21_23.png)\n","date":"April 8, 2012","externalUrl":null,"permalink":"/posts/2012-04-08-quickview/","section":"Posts","summary":"Out of the box Quick View (press Space in Finder) behaviour on unregistered files is not very useful: it shows huge Unix icon instead of content of file.\nThis is default for files like Makefile or build.gradle\nThis plugin makes it go away and show text file for all UTIs that are plain text: http://whomwah.github.com/qlstephen/\nInstallation:\nopen the DMG file copy QLStephen.qlgenerator to /Users/\u003c\u003cUSERNAME\u003e\u003e/Library/QuickLook/QLStephen.qlgenerator That’s it.\nNow it looks like this:\n","title":"How to make unregistered files work in Quick View on OS-X","type":"post"},{"content":" both Wikis are backed by Git repo both allow local edit Gollum # See https://github.com/github/gollum#readme\nInstallation: http://alblue.bandlem.com/2011/05/git-tip-of-week-gollum.html\nsudo gem install gollum\nRunning # git init TestWiki gollum --page-file-dir wiki TestWiki openurl http://localhost:4567 Parsers - separate install # gem install rdiscount gem install wikicloth Get Wiki for repo # git clone URL URL: - git@github.com:radegast/dotvim.wiki.git R+W - https://radegast@github.com/radegast/dotvim.wiki.git R+W - git://github.com/radegast/dotvim.wiki.git R Pros # multiple markups supports Markdown List of all pages Questions # How to link to page in subdir ","date":"April 7, 2012","externalUrl":null,"permalink":"/posts/2012-04-07-gollum/","section":"Posts","summary":" both Wikis are backed by Git repo both allow local edit Gollum # See https://github.com/github/gollum#readme\nInstallation: http://alblue.bandlem.com/2011/05/git-tip-of-week-gollum.html\nsudo gem install gollum\nRunning # git init TestWiki gollum --page-file-dir wiki TestWiki openurl http://localhost:4567 Parsers - separate install # gem install rdiscount gem install wikicloth Get Wiki for repo # git clone URL URL: - git@github.com:radegast/dotvim.wiki.git R+W - https://radegast@github.com/radegast/dotvim.wiki.git R+W - git://github.com/radegast/dotvim.wiki.git R Pros # multiple markups supports Markdown List of all pages Questions # How to link to page in subdir ","title":"GitHub + Gollum vs BitBucket Wiki","type":"post"},{"content":"","date":"April 7, 2012","externalUrl":null,"permalink":"/tags/wiki/","section":"Tags","summary":"","title":"Wiki","type":"tags"},{"content":" Notes from weekend hack: # Project is in Bitbucket - https://bitbucket.org/miroadamy/atgdiagram/overview\nRun # in Diagrams/ATGDiagram\nRadegast:ATGDiagram miro$ groovy -cp src src/listATGModules.groovy -e -m TWeStore.eStore \u0026gt;uml/test2.uml Radegast:ATGDiagram miro$ ./processUml.sh uml/test2.uml Radegast:ATGDiagram miro$ open uml/test2.png Radegast:ATGDiagram miro$ =\u0026gt; Output test2.uml\nthe \u0026lsquo;.\u0026rsquo; in names is converted to \u0026lsquo;_\u0026rsquo; - GraphViz does not like it the \u0026lsquo;-\u0026rsquo; in names detto Using ATG_ROOT from environment variable $ATG_ROOT: /opt/ATG/ATG10.0.2 Using /opt/ATG/ATG10.0.2 installation Dependants of module TWeStore.eStore =\u0026gt; [DCS.Search.Query, B2CCommerce, DAF.Search.Query, DAF.Search.Base, DCS.Search.common, DPS.Search.Index, DAF.Search.common, DAS-UI, DCS.Search.Index, DPS, DCS, DCS.Search.CustomCatalogs, DCS.Search.CustomCatalogs.Query, DCS.Search.CustomCatalogs.Index, DAF.Search.Routing, DCS.Search.CustomCatalogs.common, DAF.Search.Index, DSS, DCS.CustomCatalogs, DAS] @startuml Object TWeStore_eStore Object DCS Object B2CCommerce Object DCS_Search_CustomCatalogs Object DAF_Search_Routing Object DCS_CustomCatalogs Object DPS Object DCS_Search_CustomCatalogs_Query Object DAF_Search_Base Object DCS_Search_CustomCatalogs_Index Object DSS Object DAS_UI Object DCS_Search_Query Object DCS_Search_CustomCatalogs_common Object DAS Object DCS_Search_Index Object DAF_Search_Query Object DCS_Search_common Object DPS_Search_Index Object DAF_Search_Index Object DAF_Search_common TWeStore_eStore \u0026lt;|-- DCS TWeStore_eStore \u0026lt;|-- DCS_CustomCatalogs TWeStore_eStore \u0026lt;|-- B2CCommerce TWeStore_eStore \u0026lt;|-- DCS_Search_CustomCatalogs TWeStore_eStore \u0026lt;|-- DAF_Search_Routing DCS \u0026lt;|-- DPS DCS \u0026lt;|-- DSS B2CCommerce \u0026lt;|-- DCS DCS_Search_CustomCatalogs \u0026lt;|-- DCS_Search_CustomCatalogs_Index DCS_Search_CustomCatalogs \u0026lt;|-- DCS_Search_CustomCatalogs_Query DAF_Search_Routing \u0026lt;|-- DAS_UI DAF_Search_Routing \u0026lt;|-- DAF_Search_Base DCS_CustomCatalogs \u0026lt;|-- DCS DPS \u0026lt;|-- DAS DCS_Search_CustomCatalogs_Query \u0026lt;|-- DCS_Search_Query DCS_Search_CustomCatalogs_Query \u0026lt;|-- DCS_Search_CustomCatalogs_common DAF_Search_Base \u0026lt;|-- DAS_UI DCS_Search_CustomCatalogs_Index \u0026lt;|-- DCS_Search_Index DCS_Search_CustomCatalogs_Index \u0026lt;|-- DCS_Search_CustomCatalogs_common DSS \u0026lt;|-- DPS DAS_UI \u0026lt;|-- DAS DCS_Search_Query \u0026lt;|-- DAF_Search_Query DCS_Search_Query \u0026lt;|-- DCS_Search_common DCS_Search_Query \u0026lt;|-- DCS DCS_Search_CustomCatalogs_common \u0026lt;|-- DCS_Search_common DCS_Search_CustomCatalogs_common \u0026lt;|-- DCS_CustomCatalogs DCS_Search_Index \u0026lt;|-- DPS_Search_Index DCS_Search_Index \u0026lt;|-- DCS_Search_common DCS_Search_Index \u0026lt;|-- DCS DAF_Search_Query \u0026lt;|-- DAF_Search_common DCS_Search_common \u0026lt;|-- DAF_Search_common DCS_Search_common \u0026lt;|-- DCS DPS_Search_Index \u0026lt;|-- DPS DPS_Search_Index \u0026lt;|-- DAF_Search_Index DAF_Search_Index \u0026lt;|-- DAS_UI DAF_Search_Index \u0026lt;|-- DAF_Search_Base DAF_Search_common \u0026lt;|-- DAS_UI DAF_Search_common \u0026lt;|-- DAF_Search_Base DAF_Search_common \u0026lt;|-- DAF_Search_Routing @enduml Visualization (uml/test2.png) # Other functions # Radegast:ATGDiagram miro$ groovy -cp src src/listATGModules.groovy Cannot determine ATG installation directory usage: groovy listATGModules.groovy -a,--list-all List all modules -d,--debug Provide extra debug information -e,--env Use environment variable ATG_ROOT -h,--help Show usage information -m,--mod-dep \u0026lt;module\u0026gt; Show recursive dependencies of a module and UM diagram for it -p,--gen-plantuml Generate PlantUML format -r,--atg-root \u0026lt;atgRoot\u0026gt; Installation directory of the ATG - full path that contains DAS subdirectory ","date":"April 2, 2012","externalUrl":null,"permalink":"/posts/2012-04-02-atg-module-graph/","section":"Posts","summary":"Notes from weekend hack: # Project is in Bitbucket - https://bitbucket.org/miroadamy/atgdiagram/overview\nRun # in Diagrams/ATGDiagram\nRadegast:ATGDiagram miro$ groovy -cp src src/listATGModules.groovy -e -m TWeStore.eStore \u003euml/test2.uml Radegast:ATGDiagram miro$ ./processUml.sh uml/test2.uml Radegast:ATGDiagram miro$ open uml/test2.png Radegast:ATGDiagram miro$ =\u003e Output test2.uml\nthe ‘.’ in names is converted to ‘_’ - GraphViz does not like it the ‘-’ in names detto Using ATG_ROOT from environment variable $ATG_ROOT: /opt/ATG/ATG10.0.2 Using /opt/ATG/ATG10.0.2 installation Dependants of module TWeStore.eStore =\u003e [DCS.Search.Query, B2CCommerce, DAF.Search.Query, DAF.Search.Base, DCS.Search.common, DPS.Search.Index, DAF.Search.common, DAS-UI, DCS.Search.Index, DPS, DCS, DCS.Search.CustomCatalogs, DCS.Search.CustomCatalogs.Query, DCS.Search.CustomCatalogs.Index, DAF.Search.Routing, DCS.Search.CustomCatalogs.common, DAF.Search.Index, DSS, DCS.CustomCatalogs, DAS] @startuml Object TWeStore_eStore Object DCS Object B2CCommerce Object DCS_Search_CustomCatalogs Object DAF_Search_Routing Object DCS_CustomCatalogs Object DPS Object DCS_Search_CustomCatalogs_Query Object DAF_Search_Base Object DCS_Search_CustomCatalogs_Index Object DSS Object DAS_UI Object DCS_Search_Query Object DCS_Search_CustomCatalogs_common Object DAS Object DCS_Search_Index Object DAF_Search_Query Object DCS_Search_common Object DPS_Search_Index Object DAF_Search_Index Object DAF_Search_common TWeStore_eStore \u003c|-- DCS TWeStore_eStore \u003c|-- DCS_CustomCatalogs TWeStore_eStore \u003c|-- B2CCommerce TWeStore_eStore \u003c|-- DCS_Search_CustomCatalogs TWeStore_eStore \u003c|-- DAF_Search_Routing DCS \u003c|-- DPS DCS \u003c|-- DSS B2CCommerce \u003c|-- DCS DCS_Search_CustomCatalogs \u003c|-- DCS_Search_CustomCatalogs_Index DCS_Search_CustomCatalogs \u003c|-- DCS_Search_CustomCatalogs_Query DAF_Search_Routing \u003c|-- DAS_UI DAF_Search_Routing \u003c|-- DAF_Search_Base DCS_CustomCatalogs \u003c|-- DCS DPS \u003c|-- DAS DCS_Search_CustomCatalogs_Query \u003c|-- DCS_Search_Query DCS_Search_CustomCatalogs_Query \u003c|-- DCS_Search_CustomCatalogs_common DAF_Search_Base \u003c|-- DAS_UI DCS_Search_CustomCatalogs_Index \u003c|-- DCS_Search_Index DCS_Search_CustomCatalogs_Index \u003c|-- DCS_Search_CustomCatalogs_common DSS \u003c|-- DPS DAS_UI \u003c|-- DAS DCS_Search_Query \u003c|-- DAF_Search_Query DCS_Search_Query \u003c|-- DCS_Search_common DCS_Search_Query \u003c|-- DCS DCS_Search_CustomCatalogs_common \u003c|-- DCS_Search_common DCS_Search_CustomCatalogs_common \u003c|-- DCS_CustomCatalogs DCS_Search_Index \u003c|-- DPS_Search_Index DCS_Search_Index \u003c|-- DCS_Search_common DCS_Search_Index \u003c|-- DCS DAF_Search_Query \u003c|-- DAF_Search_common DCS_Search_common \u003c|-- DAF_Search_common DCS_Search_common \u003c|-- DCS DPS_Search_Index \u003c|-- DPS DPS_Search_Index \u003c|-- DAF_Search_Index DAF_Search_Index \u003c|-- DAS_UI DAF_Search_Index \u003c|-- DAF_Search_Base DAF_Search_common \u003c|-- DAS_UI DAF_Search_common \u003c|-- DAF_Search_Base DAF_Search_common \u003c|-- DAF_Search_Routing @enduml Visualization (uml/test2.png) # ","title":"ATG module graph","type":"post"},{"content":" GraphViz # installed from package See http://www.graphviz.org/ Radegast:diagrams miro$ dot -V dot - graphviz version 2.28.0 (20110509.1545) Radegast:diagrams miro$ which dot dot is /usr/local/bin/dot SchemaSpy # installed in /opt/diagrams see http://schemaspy.sourceforge.net/ Radegast:schemaSpy miro$ java -jar ./schemaSpy_5.0.0.jar -cp .:/Users/miro/lib/java/jdbc/mysql-connector-java-5.1.7-bin.jar -t mysql -o library -host localhost -u twt_dX_core -db twt_dX_core -p twt_dX_core Using database properties: [./schemaSpy_5.0.0.jar]/net/sourceforge/schemaspy/dbTypes/mysql.properties Gathering schema details....................................................................................................................................................................................................................................................................................................................................................(36sec) Writing/graphing summary..... .......(353sec) Writing/diagramming details.................................................................................................................................................................................................................................................................................................................................................(104sec) Wrote relationship details of 337 tables/views to directory \u0026#39;library\u0026#39; in 494 seconds. View the results by opening library/index.html Radegast:schemaSpy miro$ Radegast:schemaSpy miro$ ll total 904 PlantUML # installed in /opt/diagrams manual is attached: PlantUML Language Reference Guide.pdf See http://plantuml.sourceforge.net/classes.html in /opt/plantUML-DEMO/ there are sample files @startuml img/sequence_img009.png Alice -\u0026gt; Bob: Authentication Request alt successful case Bob -\u0026gt; Alice: Authentication Accepted else some kind of failure Bob -\u0026gt; Alice: Authentication Failure group My own label Alice -\u0026gt; Log : Log attack start loop 1000 times Alice -\u0026gt; Bob: DNS Attack end Alice -\u0026gt; Log : Log attack end end else Another type of failure Bob -\u0026gt; Alice: Please repeat end @enduml PlantUML Dependency Reverse Engineering # Processes source code and generates the PlantUML Class description file\nYou can run PlantUML Dependency using the following simplest command : java -jar plantuml-dependency-1.0.1.jar -o plantuml.txt This will look for all java source files into the current directory recursively, creating a plantuml.txt file describing the PlantUML class diagram description. For processing an other directory, you can use : java -jar plantuml-dependency-1.0.1.jar -b \u0026#34;~/directory1\u0026#34; To filter source files to parse, you can use ANT patterns to include or exclude files : java -jar plantuml-dependency-1.0.1.jar -i **/*Test*.java -e **/*Generated*.java To change the output file path, you can use : java -jar plantuml-dependency-1.0.1.jar -o \u0026#34;/directory1/test-plantuml.txt\u0026#34; Running it from Ant source tree # Radegast:platUml-DEMO miro$ java -jar ../plantuml-dependency-1.1.0-jar-with-dependencies.jar -b /Users/miro/src/apache-ant-1.8.1/src/main -o ant-sources.txt ## ... edit ant-sources.txt to include img/target.png and make it smaller java -Xmx3096m -jar ../plantuml.jar ant-sources.txt ","date":"March 30, 2012","externalUrl":null,"permalink":"/posts/2012-03-30-diagram-generation/","section":"Posts","summary":"GraphViz # installed from package See http://www.graphviz.org/ Radegast:diagrams miro$ dot -V dot - graphviz version 2.28.0 (20110509.1545) Radegast:diagrams miro$ which dot dot is /usr/local/bin/dot SchemaSpy # installed in /opt/diagrams see http://schemaspy.sourceforge.net/ Radegast:schemaSpy miro$ java -jar ./schemaSpy_5.0.0.jar -cp .:/Users/miro/lib/java/jdbc/mysql-connector-java-5.1.7-bin.jar -t mysql -o library -host localhost -u twt_dX_core -db twt_dX_core -p twt_dX_core Using database properties: [./schemaSpy_5.0.0.jar]/net/sourceforge/schemaspy/dbTypes/mysql.properties Gathering schema details....................................................................................................................................................................................................................................................................................................................................................(36sec) Writing/graphing summary..... .......(353sec) Writing/diagramming details.................................................................................................................................................................................................................................................................................................................................................(104sec) Wrote relationship details of 337 tables/views to directory 'library' in 494 seconds. View the results by opening library/index.html Radegast:schemaSpy miro$ Radegast:schemaSpy miro$ ll total 904 PlantUML # installed in /opt/diagrams manual is attached: PlantUML Language Reference Guide.pdf See http://plantuml.sourceforge.net/classes.html in /opt/plantUML-DEMO/ there are sample files @startuml img/sequence_img009.png Alice -\u003e Bob: Authentication Request alt successful case Bob -\u003e Alice: Authentication Accepted else some kind of failure Bob -\u003e Alice: Authentication Failure group My own label Alice -\u003e Log : Log attack start loop 1000 times Alice -\u003e Bob: DNS Attack end Alice -\u003e Log : Log attack end end else Another type of failure Bob -\u003e Alice: Please repeat end @enduml ","title":"Diagram generation - plain text approach","type":"post"},{"content":" Few gitbits to remember # Pushing new local branch to remote repo: # Find a ref that matches experimental in the source repository (most likely, it would findrefs/heads/experimental), and update the same ref (e.g. refs/heads/experimental) in origin repository with it.\nIf experimental did not exist remotely, it would be created.\ngit push origin experimental\nThis is the same as:\ngit push origin experimental:refs/heads/experimental\nCreate the branch experimental in the origin repository by copying the current experimental branch.\nThis form is only needed to create a new branch or tag in the remote repository when the local name and the remote name are different; otherwise, the ref name on its own will work.\nRemove all Idea files # git rm --cached `find . -name \u0026#34;*.iml\u0026#34;` ","date":"March 25, 2012","externalUrl":null,"permalink":"/posts/2012-03-25-few-git-tricks/","section":"Posts","summary":"Few gitbits to remember # Pushing new local branch to remote repo: # Find a ref that matches experimental in the source repository (most likely, it would findrefs/heads/experimental), and update the same ref (e.g. refs/heads/experimental) in origin repository with it.\nIf experimental did not exist remotely, it would be created.\n","title":"Few gitbits to remember","type":"post"},{"content":" Issue # In dotvim repo, I used readonly URL for cloning the repository. Now I have created local branch ( linux-vm ) to track Linux specific font settings and need them to push up.\nAfter creating new SSH pair and adding to GitHub, does not work\n[tkuser@cplx-dev-vf .vim]$ git status # On branch linux-vm nothing to commit (working directory clean)[tkuser@cplx-dev-vf .vim]$ git push origin linux-vm fatal: remote error: You can\u0026#39;t push to git://github.com/radegast/dotvim.git Use git@github.com:radegast/dotvim.git [tkuser@cplx-dev-vf .vim]$ git remote show origin * remote origin Fetch URL: git://github.com/radegast/dotvim.git Push URL: git://github.com/radegast/dotvim.git HEAD branch: master Remote branch: master tracked Local branch configured for \u0026#39;git pull\u0026#39;: master merges with remote master Local ref configured for \u0026#39;git push\u0026#39;: master pushes to master (up to date) [tkuser@cplx-dev-vf .vim]$ git remote set-url --push origin git@github.com:radegast/dotvim.git [tkuser@cplx-dev-vf .vim]$ git remote show origin * remote origin Fetch URL: git://github.com/radegast/dotvim.git Push URL: git@github.com:radegast/dotvim.git HEAD branch: master Remote branch: master tracked Local branch configured for \u0026#39;git pull\u0026#39;: master merges with remote master Local ref configured for \u0026#39;git push\u0026#39;: master pushes to master (up to date) [tkuser@cplx-dev-vf .vim]$ git push origin linux-vm Enter passphrase for key \u0026#39;/home/tkuser/.ssh/id_rsa\u0026#39;: Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 306 bytes, done. Total 3 (delta 1), reused 0 (delta 0) To git@github.com:radegast/dotvim.git * [new branch] linux-vm -\u0026gt; linux-vm The important line is\ngit remote set-url \u0026ndash;push origin git@github.com:radegast/dotvim.git\nNotes: # creating the pair: http://help.github.com/linux-set-up-git/ Keygen # [tkuser@cplx-dev-vf ~]$ ssh-keygen -t rsa -C \u0026#34;miro.adamy+cplx-dev-vf-osx@gmail.com\u0026#34; Generating public/private rsa key pair. Enter file in which to save the key (/home/tkuser/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/tkuser/.ssh/id_rsa. Your public key has been saved in /home/tkuser/.ssh/id_rsa.pub. The key fingerprint is: 4e:17:89:ea:b3:57:51:78:e3:27:dc:d2:b1:2a:0e:86 miro.adamy+cplx-dev-vf-osx@gmail.com Validation\n[tkuser@cplx-dev-vf .ssh]$ cd [tkuser@cplx-dev-vf ~]$ ssh -T git@github.com Enter passphrase for key \u0026#39;/home/tkuser/.ssh/id_rsa\u0026#39;: Hi radegast! You\u0026#39;ve successfully authenticated, but GitHub does not provide shell access. ","date":"March 21, 2012","externalUrl":null,"permalink":"/posts/2012-03-21-remote-origin/","section":"Posts","summary":"Issue # In dotvim repo, I used readonly URL for cloning the repository. Now I have created local branch ( linux-vm ) to track Linux specific font settings and need them to push up.\nAfter creating new SSH pair and adding to GitHub, does not work\n[tkuser@cplx-dev-vf .vim]$ git status # On branch linux-vm nothing to commit (working directory clean)[tkuser@cplx-dev-vf .vim]$ git push origin linux-vm fatal: remote error: You can't push to git://github.com/radegast/dotvim.git Use git@github.com:radegast/dotvim.git [tkuser@cplx-dev-vf .vim]$ git remote show origin * remote origin Fetch URL: git://github.com/radegast/dotvim.git Push URL: git://github.com/radegast/dotvim.git HEAD branch: master Remote branch: master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date) [tkuser@cplx-dev-vf .vim]$ git remote set-url --push origin git@github.com:radegast/dotvim.git [tkuser@cplx-dev-vf .vim]$ git remote show origin * remote origin Fetch URL: git://github.com/radegast/dotvim.git Push URL: git@github.com:radegast/dotvim.git HEAD branch: master Remote branch: master tracked Local branch configured for 'git pull': master merges with remote master Local ref configured for 'git push': master pushes to master (up to date) [tkuser@cplx-dev-vf .vim]$ git push origin linux-vm Enter passphrase for key '/home/tkuser/.ssh/id_rsa': Counting objects: 5, done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 306 bytes, done. Total 3 (delta 1), reused 0 (delta 0) To git@github.com:radegast/dotvim.git * [new branch] linux-vm -\u003e linux-vm The important line is\n","title":"How to fix the remote origin from read only","type":"post"},{"content":"","date":"February 15, 2012","externalUrl":null,"permalink":"/tags/agile/","section":"Tags","summary":"","title":"Agile","type":"tags"},{"content":" Miro Manifesto # Original text of the memo, written in February 2012 and shared with limited audience, until it surfaced up as main them of the planning meeting in December 2012.\nThis is an attempt to come up with better answers to the following questions:\nwhat issues and challenges I see on our way ahead from the technology point of view and what needs to be done to address them where do I see my professional and personal career go over next 12 to 18 months and in long run how to best align those two streams In the spirit of my latest “back to the basics” obsession, it was written in Markdown format and in Vi, copied and pasted into Google Doc, btw.\nNot that it matters.\nNOTE: I have removed the names of some of the 3rd parties. Just to be safe.\nChallenges # My perspective of the \u0026ldquo;state of the union\u0026rdquo; is different from one that Steve or Mike has.\nI deal with code, with production environments, with customers asking for features and our PM/AM/BAs providing the customer with SOW and estimates.\nI am usually one of the data inputs for these estimates and (unlike AM, PM or BA) see most of these SOWs through their lifecycle: how the SOW document \u0026ldquo;spawns\u0026rdquo; code level artifacts and activities and eventually ends up as new version of EAR file running somewhere in production environment.\nTherefore what I see are not numbers, bottom lines, sales funnels and summary hours in Dovico but classes, Ant scripts, SVN repository commits, filesystems in production and actual content behind the numbers in Dovico. I see challenges and issues we encountered while creating those classes and config files, unfinished things, quick hacks and duct-tapes fixes we have left behind, hardcoded paths and messy directories with duplicate content, crazy complex flows.\nI also see elegance and design beauty, dotted i\u0026rsquo;s and crossed t\u0026rsquo;s - but not as often as I wish. I see empty Wiki pages and outdated unmaintained mess in documentation, next to work of art ready to save to PDF and publish. Between these broken windows code smells and chunks of awesomness I start to see trends and patterns and these patterns worry me.\nBoth as software engineer (or craftsman if you will) and as founder of the company.\nWe are in many aspect, as we grow, start to behave like the government: we are accumulating more and more debt and we are eating up our savings.\nIt is not money I mean, the debt being accumulated is technical debt and what is being spent are the ingredients that makes us different:\nexperience quality passion and culture. Here is what they are and how are they being consumed:\nExperience: # as we grow, we will add more and more people to work on highly complex solutions. People that will be less trained and less ready as the people we have had in 2009 when the ATG really started. These people will need to be coached, mentored and educated - before the job and on the job. Otherwise they will try to imitate what they see and \u0026ldquo;code by example\u0026rdquo;.\nIf we had high quality code base, that would not be too bad. That is however not the case. Without countermeasure the number of \u0026ldquo;it works by coincidence\u0026rdquo; situations will grow a lot - simply because the people working on project will not have deep enough understanding of all details.\nIt is not only about growing the total sum of experience in the company, it is also about moving people in and out of projects, sharing knowledge and education. We need to way more efficient way how to capture and share the experience: best practices (and worst ones to be avoided) project specific know-how required for the operations as well as vertical knowledge: payment gateways, inventory systems, toolkits and libraries. We need to move ahead the standardization and convergence of the codebases and processes, to increase the chance of reuse at all levels: concepts, patterns, integration points processes, tools and even code.\nNow when we have pretty much solo focus on ATG and ecommerce, we need to become the best experts in ATG, better than Oracle and definitely better that everybody else. Big part of this will come out of project work as longs as we try to go deeper. What will not come automatically is identifying, capturing, processing and sharing this deep expertise knowledge.\nQuality # as we grow, quality goes down unless there is a dedicated effort to work against it. Quality will go down as result less experienced teams in general, imitation of bad code (broken windows syndrome) but mainly because without quality program and early feedback it makes no difference to developer: nobody sees his/her code and explains what is wrong with it.\nWe need to identify the bad pieces so that they will not be duplicated (and same mistake will not be made several times) and eventually those identified pieces can be refactored and fixed. We also need to identify the gems and pieces that deserve to be replicated and learned from them: we need to make documentation good enough that it will be less work to use the solution that to re-invent it.\nWhen we started the ATG path in summer 2008, we did not really know much about ATG platform beyond the actual core (DAS+DPS+DSS) we used in our first projects. We were learning on our first assignments.\nSo we started with two large buckets of technical debt: one inherited mess from botched implementation and one with our own gaps and lack of experience from doing complex things we have not done before. As time progressed, we have added third bucket: code we wrote impacted by the inherited (bad) approaches. Examples are XYZ import process built on inflexible foundations.\nThe speed of us taking on new tasks and going into new areas is increasing. We are trying to define cookie cutter template that we will reuse. If this template is off, we will multiply the problem by using it, so it is in our deepest interest to get this RIGHT.\nPassion: # we have been lucky to have a pool of tested, above-average passionate employees that care available from Montage times. With more new hires and more younger generation, there will be likely less passion and less dedication.\nTo a degree, we already see it.\nWe need to create something that would at minimum prevent this from going down - or at minimum, that will keep the speed of decline to be slower than the speed of growth.\nWe need to have some mechanism that will keep the passion, the pride of craftsmanship and directions of evolution towards improvements and against the natural entropy. It is very hard to be proud when one works on crappy codebase or with tools / techniques inadequate, so the previous two are kinda pre-requisites.\nCulture: # when we started this company in early 2004, the basic urge to do it was to create a place where people would be looking forward to come to work every day, a kind of business-sane version of nerdvana where people can do great work, grow and help the customers to be successful.\nI am very proud of what we achieved so far. The growth of the company amazes me and as shareholder it makes me very happy. The challenge now is how this culture (nerdvana plus all of the qualities above - experience, quality and passion ) can be preserved and transformed in a form that would work for the company sized from below 50 to company sized between 50 to 200.\nThe fundamental challenge is that we are growing much faster than improving - or the other way, we are improving too slow for our rate of growth. Last thing I want is to curb our growth ambitions - so I am trying to focus on how to improve our improvement process and make it to catch up with growth.\nGaps that are the cause # The \u0026ldquo;spending of secret sauce\u0026rdquo; instead of creating and refining it is IMHO mainly caused by gaps.\nAmong many, here is what I see as most impacting for the delivery side of the business\nOperation / Support practice # Without operation or support practice, the projects kinda hang there and are supported by \u0026ldquo;best effort\u0026rdquo; rotation, usually victimizing the developers who were in the meantime transferred to new challenge.\nMissing handover to operation process (as there nobody to hand over to) eliminates important check in project lifecycle - projects never make it to \u0026ldquo;real production\u0026rdquo; so the chaos and state of unfinishedness persists for the whole duration of the project.\nThe consequences are that project starts with technical debt (never got over the \u0026ldquo;production ready\u0026rdquo; gate) and whether the gaps in quality, functionality are filled during the operation, really depends on how generous is the support budget.\n(Lack of) Standardization # Every project is single silo of knowledge. To certain degree this is consequence of taking over legacy apps but even in projects who build from scratch the degree of standardization between any two projects really depends on how many people were working on both of them, how willing were they to push for the \u0026ldquo;tested\u0026rdquo; approach and well the others understood the intent.\nThere is no mechanism / program / initiative that would work towards alignment, sharing, unification of techniques and tools. Whether same problem will be solved same way between project A and B depends only on whether people involved understand the other solution well enough and are willing to share. Sometimes it is harder to “take out” the piece of functionality because the last step - documenting, packaging was not done and because the approaches taken in two projects are too different. If that is the case, we will end up with differing solutions of the same problem.\n(Lack of) knowledge sharing # As corollary to the above, the only way how knowledge is shared is by sharing people among projects. If there is enough overlap, this works to a degree, but it is very inefficient, creates additional load on the knowledge providers and makes them the bottleneck.\nMost importantly, this has direct impact on our ability to scale up, deal with emergencies, people\u0026rsquo;s absence or other personal issues. The likelihood of all of which will increase a lot with bigger company.\nBy not having proper documentation and knowledge base, we are not using the most precious learning and training tool. No formal training by ATG can be compared by detailed review of a properly done ATG project, that has good high level documentation.\nIncomplete Project Management # This is not my territory, but here is what I see. We spend a lot of time in producing guestimates and spend a lot of mental energy to make them to be more like estimates.\nWe end up with SOW and work breakdown that has certain tasks and allotted hours.\nOur tracking of the real time spent on the tasks is awfully incomplete: we capture of part of the true costs. Because of the people overlap, lots of unfinished business we continue to fool ourselves that we did X in 100 hours, while in reality it was only 80% of X done, and of this 80% maybe 15% had to be refactored and fixed. Altogether we spent 150 hours, only the additional 50 hours was hidden as support fixes or (if we were lucky) got fixed as part of next CR. This way we are spending money out of our pockets.\nWe are also leaving money on the table by not identifying the parts of already done and using them.\nThe reason why is because there is not enough documentation, extraction and post-processing done on any given project. It can be argued who should carry the costs of this post-processing but it can be done both ways: if it is TW cost, TW can get the benefit of huge margin for the second sale. If customer, we can pass the benefit to customer. But back to the original: project management is incomplete because it does not have feedback about true cost and quality.\nWith this data, we would see\nmisalignment between the time allotments and real effort mis-estimates undersold projects legacy impact All this creates pressure and opportunities to cut corners. And boy, we sometimes do cut corners.\n(Lack of) Feedback # Not only project managers are victims of the little feedback. The more impacted are developers.\nWith no process to identify the quality issues there cannot be any proper professional feedback to developers - the quality is not part of career evaluation / personal reviews.\nThis also contributes to lack of excitement caused by impact of quality. When nobody notices what will make developers want to write a great code ? Add emergencies, stress and lack mentoring and coaching, and we will quickly become just another lackluster software development shop.\nAbsurdly enough, we are (to a certain degree) make developers responsible for their billable hours - something over which they have very little control.\nWe do not however make people responsible for the quality of their work - something they actually CAN control themselves.\nThings that needs to be done to address the challenges above\nEstablish quality program with the following\nmake code reviews non-optional part of the project lifecycle make architecture reviews non-optional condition for release environment / project reviews after major project event (release to production) feed information from reviews into documentation make quality part of the evaluation Create Operations / Support practice # define “production ready” gate code quality environment quality test pass documentation availability define handover strategy between dev and prod run operations as operations, not as development shop Fix documentation issue # make documentation part of the project completeness allow people circulation without impact to projects and clients define process of review and maintenance of documentation on the live projects move people between projects - the documentation must be used Education and Improvement programs # make participation in these (both passive and active) part of evaluation establish process of rotation people between projects to give them exposure and to test the knowledge transfer derive experience from reviews ","date":"February 15, 2012","externalUrl":null,"permalink":"/posts/2012-02-15-miro-manifesto/","section":"Posts","summary":"Miro Manifesto # Original text of the memo, written in February 2012 and shared with limited audience, until it surfaced up as main them of the planning meeting in December 2012.\nThis is an attempt to come up with better answers to the following questions:\nwhat issues and challenges I see on our way ahead from the technology point of view and what needs to be done to address them where do I see my professional and personal career go over next 12 to 18 months and in long run how to best align those two streams In the spirit of my latest “back to the basics” obsession, it was written in Markdown format and in Vi, copied and pasted into Google Doc, btw.\n","title":"Miro Manifesto","type":"post"},{"content":"Part of the beauty of JSP development is the easy of trying out the change. All you have to do is edit the JSP file, save it and reload the page. Yesterday I got caught by surprise by not being able to do exactly that. I saw some strange behaviour in an EL expression used JSP tag. As it was nothing ATG specific, I decided to try it out in plain old Tomcat rather than full ATG application. So I located the instance of Tomcat 5.5 (I always have couple of Tomcats lying around) and being lazy, I decided to inject the change into out-of the box jsp-examples Web application that comes with it.\nI picked a victim JSP to be modified (jsp2/el/basic-comparison.jsp), made my change, reloaded page - nothing. I must have forgotten to save the file, did it again - nothing. Weird. Maybe browser caching. Cmd-Shift-R - nothing. Tried different browser - it showed unchanged file as before. Definitely not a browser issue. The most logical explanation would be that I am editing different file than reloading: so I verified that the JSP file I edited is indeed under WebApps, that correct version of Tomcat was started. It was. There was no context redirection in place but to be sure, I unzipped pristine copy of apache-tomcat-5.5.31.zip (I have couple of those around as well), copied the JSP there, started it - same thing.\nReally weird.\nFew more experiments showed that no change to any JSP page under jsp-examples was visible. Removing JSP page caused 404 error as expected, but as soon as the page was there, it reappeared in original pristine version. At this point, I started to suspect there is something fishy with the jsp-examples application itself. And it was. Brief check of the web.xml showed that it is quite long (24K) and that it contains declaration:\n\u0026lt;servlet\u0026gt; \u0026lt;servlet-name\u0026gt;org.apache.jsp.jsp2.el.basic_002dcomparisons_jsp\u0026lt;/servlet-name\u0026gt; \u0026lt;servlet-class\u0026gt;org.apache.jsp.jsp2.el.basic_002dcomparisons_jsp\u0026lt;/servlet-class\u0026gt; \u0026lt;/servlet\u0026gt; .... \u0026lt;servlet-mapping\u0026gt; \u0026lt;servlet-name\u0026gt;org.apache.jsp.jsp2.el.basic_002dcomparisons_jsp\u0026lt;/servlet-name\u0026gt; \u0026lt;url-pattern\u0026gt;/jsp2/el/basic-comparisons.jsp\u0026lt;/url-pattern\u0026gt; \u0026lt;/servlet-mapping\u0026gt; and suddenly it all made sense.\nAs long as the JSP file was present (Tomcat checks), it\u0026rsquo;s content was completely ignored and the request for /jsp2/el/basic-comparisons.jsp was served by COMPILED class /webapps/jsp-examples/WEB-INF/classes/org/apache/jsp/jsp2/el/basic_002dcomparisons_jsp.class - which of course did not contain any of the JSP file changes. When I removed file, Tomcat reported 404 a- the check for file existence comes before check for URL mapping apparently.\nMoral of the story: being lazy causes one has to do more work but often learns something new. Had I created fresh new WebApp, none of these mappings were present and I would never realized what is Tomcat 5 doing behind the scenes.\nBtw, in Tomcat 6 the mappings are gone and everything behaves as expected. Although this is not technically a bug - but a feature - it is unfortunate that this optimization is used exactly in one application that can be used by newbie developer learning JSP for experimentation and not seeing it\u0026rsquo;s change can confuse the hell out of them. Especially when googling the issue will very likely sending him/her in completely wrong direction - suggesting reconfiguring Jasper, playing with valves and internals of Tomcat configuration.\n","date":"July 24, 2011","externalUrl":null,"permalink":"/posts/2011-07-24-tomcat-5-not-reloading-changes-in-jsp/","section":"Posts","summary":"Part of the beauty of JSP development is the easy of trying out the change. All you have to do is edit the JSP file, save it and reload the page. Yesterday I got caught by surprise by not being able to do exactly that. I saw some strange behaviour in an EL expression used JSP tag. As it was nothing ATG specific, I decided to try it out in plain old Tomcat rather than full ATG application. So I located the instance of Tomcat 5.5 (I always have couple of Tomcats lying around) and being lazy, I decided to inject the change into out-of the box jsp-examples Web application that comes with it.\n","title":"Tomcat 5 not reloading changes in JSP","type":"post"},{"content":"It may be too early to express opinions about something so new as Google+, but in the short few days I was playing with it, I started to like it a lot. Many bloggers consider it to be a Facebook killer - and it (unlike two previous Google attempts on social networking) eventually may become that. Conceptually, however it is much closer to Twitter than Facebook.\nThe biggest difference is that in G+ there is no peer relation - \"friendship\" that needs to be confirmed by both parties. Both ends are disconnected in Google+ - set of people whose updates you see in your stream and set of people that see your updates is not the same and can be in extreme case disjunct.\nIn G+, like in Twitter, everybody chooses set of people whose updates you want to see - you \"follow\" people. This following does not require any approval on their end. Unlike Twitter, you can easily organize the people you follow into groups (circles) and with single click limit the news stream only to members of this group (where one person can be in many groups). It is like having multiple Twitter accounts, each with different set of people followed and switching identities.\nOn broadcasting side, you can select the target audience for each post by addressing the message to be visible publicly (Twitter default), by any member of your circles, your extended circles (kind of \"friends of friends\"), one or several named circles, or even named set of people from your circles. Whether your message will actually appear in their message stream depends on whether the addressee did add you into their circles. Twitter does allow you only public updates. (Yes, ok, there are \"protected tweets\" by who uses them ?). Facebook allows you updates only for all your friends or single FB group.\nFor example, I have group named Following with members like Andy Ihnatko, Leo Laporte, Leo Babauta and other internet celebrities. Clicking on the circle will show me all public updates from these people, but it would contain none of the posts made e.g. by Andy for his circles - of which I am not member of. Similarly, should I post an update for the \"Following\" circle, Andy would never see it in his news stream (despite of that I do have him in my circles) as I am not member of his circles. This way Google created incredibly flexible framework that can deliver any mode of communication available from Twitter and Facebook:\n1) Twitter following: see above\n2) Facebook friends: both parties add the other to circles\n3) Facebook groups: named circle (plus possibility of multiple groups and administration that does not suck)\n4) Friends of friends: extended circles\n5) direct message to person (in your circles): update with single person recipient\nWhat G+ does not have (yet) are applications/games and public developer API. I am pretty sure that promised availability of the later will cause the explosion in the first. It will be very interesting to see the impact of this new, much more flexible \"trust model\" on the kinds of applications available.\n","date":"July 11, 2011","externalUrl":null,"permalink":"/posts/2011-07-11-google-is-superset-of-both-facebook-and-twitter/","section":"Posts","summary":"It may be too early to express opinions about something so new as Google+, but in the short few days I was playing with it, I started to like it a lot. Many bloggers consider it to be a Facebook killer - and it (unlike two previous Google attempts on social networking) eventually may become that. Conceptually, however it is much closer to Twitter than Facebook.\nThe biggest difference is that in G+ there is no peer relation - \"friendship\" that needs to be confirmed by both parties. Both ends are disconnected in Google+ - set of people whose updates you see in your stream and set of people that see your updates is not the same and can be in extreme case disjunct.\n","title":"Google+ is superset of both Facebook and Twitter","type":"post"},{"content":"After being away for over 4 months, I am back on Twitter. No, I did not miss the stream of 160 character mixture of news, trivia, white noise and occasional nuggets. Three main reasons:\n1) Twitter seems to to become unavoidable - more and more services assume that one has twitter account. Many cyberevents rules start with \"retweet this\" or \"tweet that\" which of course one cannot do without Twitter account\n2) Direct messaging via Twitter is one very convenient method how to add information to many service: new todo in Toodledo, Evernote and so on. It is MUCH faster than starting any client on an iPhone.\n3) Twitter is after all the best medium for sharing links. Facebook does not cut it if you want to keep friend count reasonable so there is a gap between Facebook and LinkedIn\nAlas, I am back, with my old handle 'miroadamy'.\nHello - Nael and the gang ...\n","date":"June 19, 2011","externalUrl":null,"permalink":"/posts/2011-06-19-back-to-twitter/","section":"Posts","summary":"After being away for over 4 months, I am back on Twitter. No, I did not miss the stream of 160 character mixture of news, trivia, white noise and occasional nuggets. Three main reasons:\n1) Twitter seems to to become unavoidable - more and more services assume that one has twitter account. Many cyberevents rules start with \"retweet this\" or \"tweet that\" which of course one cannot do without Twitter account\n","title":"Back to Twitter","type":"post"},{"content":"I have been Cultured Code customer for over 2 years and used multiple their products: Things on OS-X, Things for iPad and iPhone on daily basis.\nNot any more.\nI am definitely giving up on Things and Cultured Code products.\nThe reason why is sheer frustration from long wait on usable synchronization between Things on Mac, iPad and iPhone. Something that have been discussed, promised, chewed over 2 years and that still does not work.\nIn theory, you *can* synchronize as long as Mac and iPad / iPhone are in the same wireless network and can see each other. Things on Mac must be running and when Things on iPad/iPhone starts, they find each other and exchange data. It works most of the time, until it stops. With a bit of luck and some tweaking, one may be lucky and get it back to working order. Or not.\nIt happened to me several times that for no particular reason, iPad started the synchronization but never completed. Sometimes restarting iPad or Mac helped. Sometimes not. Sometimes I managed to fix the problem by unregistering the iPad and adding it back. When this remedy failed, in frustration, I tried to contact CC technical support. Here is the answer\nHi, Thank you for your inquiry. We are working on our own cloud sync solution that will allow for multi-device-sync (Mac / iPhone / iPad) using whatever network is available (Wifi / Edge / 3G). See: http://culturedcode.com/status That's the most requested feature currently. At present I can't give you a time frame, though, when this is going to be ready. Regards, Roman. Things Support Cultured Code They have been working on synchronization for well over 2 years now, if I remember correctly, which is about 18 months too long. What kind of project management is that they still do not have a time frame for completion ? This is not perfectionism, this smells like Cultured Code is another product company that was great once but lost its mojo and capability to deliver. Things may be the most beautifully designed GTD application out there - but how long will pleasure from using shiny toy compensate for lack of basic functionality ?\nAfter reviewing the landscape of GTD apps in 2011 I am now settling on combination of Toodledo and Evernote. Toodledo is basically a Web application with several iPad / iPhone clients. There is probably no OS-X desktop client that would come close to elegance of Things. Yet. And the web UI is kinda busy - but boy, it is *very* *very* functional. The synchronization with iPad works like charm, asynchronously.\nAnd I doubt it took the Toodledo team 24 months to solve ...\n","date":"June 18, 2011","externalUrl":null,"permalink":"/posts/2011-06-18-dear-cultured-code-you-are-history/","section":"Posts","summary":"I have been Cultured Code customer for over 2 years and used multiple their products: Things on OS-X, Things for iPad and iPhone on daily basis.\nNot any more.\nI am definitely giving up on Things and Cultured Code products.\nThe reason why is sheer frustration from long wait on usable synchronization between Things on Mac, iPad and iPhone. Something that have been discussed, promised, chewed over 2 years and that still does not work.\n","title":"Dear Cultured Code, you are history ...","type":"post"},{"content":"Few weeks ago, I canceled my Twitter account and stopped using Twitter altogether. I do not miss it at all.\nThe next vector of distraction to be brought under control is Facebook. This is a tougher nut to crack - because of wide variety of people in my circle of friends, Facebook plays many different roles.\nIt is a connection to old friends and colleagues from the old continent and old country. It is a family connection. It is a connection to people that are not on FB through their friends or relatives that are. It is a link to people I worked with and wanted to keep in touch. It is a link to people I share common interest with This variety creates a problem of itself (which is multiplied by English/non English division). Tool that does too many things, does not do them very well.\nHonestly, I do not understand how some people can maintain hundreds of \"friends\". The group of this size generates so much noise, so many updates that the news stream becomes close to useless. One can always hide updates from most significant \"link spammers\" but that opens up a question: is there any point in providing a view into your life to somebody whose updates you do not read anyway ?\nFirst attempt to solve this is to separate the \"private world\" and work. In my case, there is no clear boundary as I am fortunate to work with so many of my close personal friends (many of which are on FB) and in my current employment I am lucky to consider many of the people I work with to be much more than just work buddies. Nevertheless, my goal is to get down to two digit number of Facebook friends.\nTo achieve that, I would like to ask some of my current Facebook friends to reconnect on LinkedIn. I absolutely want to stay in touch, just using different channel.\nMy public profile is here https://www.linkedin.com/in/miroadamy.\nSee you there\n","date":"April 7, 2011","externalUrl":null,"permalink":"/posts/2011-04-07-facebook-or-linkedin-thats-the-question/","section":"Posts","summary":"Few weeks ago, I canceled my Twitter account and stopped using Twitter altogether. I do not miss it at all.\nThe next vector of distraction to be brought under control is Facebook. This is a tougher nut to crack - because of wide variety of people in my circle of friends, Facebook plays many different roles.\nIt is a connection to old friends and colleagues from the old continent and old country. It is a family connection. It is a connection to people that are not on FB through their friends or relatives that are. It is a link to people I worked with and wanted to keep in touch. It is a link to people I share common interest with This variety creates a problem of itself (which is multiplied by English/non English division). Tool that does too many things, does not do them very well.\n","title":"Facebook or LinkedIn - that's the question","type":"post"},{"content":"Since 2005 when I switched to GMail, I was living in browser. For better or worse, I learn to put up with issues like speed, lack of hotkeys, UI that is not as responsive as it should be, drag and drop that works most of the time. To be fair, in these five years browsers and GMail UI improved tremendously. It was rational decision to trade all these for simplicity of the UI.\nEven after switching to Mac in 2006 - first for home, a year later for everything did not change this, I kept using browser despite better choice. Apple Mail may be decent client but it never felt quite right and otherwise decent Thunderbird had always issues with trading off multi-platform reach for integration and true Mac-ness.\nAll of this changed today after installing Sparrow. It is all I ever wanted - IMAP based access that really works, with minimalistic but elegant interface, Twitter like simplicity and that special sauce which discriminates great OS-X application from average. For very reasonable price $9.99 available in App Store.\n99% of all GMail features are there - the only one I had to sacrifice is multiple signatures for single account. Before, all my work email was redirected and merged into my private GMail account, set up with multiple aliases and GMail was smart enough to pick different signature based on sending address. To do the same, I had to cut the redirect. Luckily, both Sparrow as well as iPad mail client support multiple accounts so I have access to all accounts inside single client on Macbook or iPad.\nSparrow - http://www.sparrowmailapp.com/, available in App Store.\nHighly recommended.\n\u0026nbsp;\n","date":"February 11, 2011","externalUrl":null,"permalink":"/posts/2011-02-11-better-gmail-than-gmail/","section":"Posts","summary":"Since 2005 when I switched to GMail, I was living in browser. For better or worse, I learn to put up with issues like speed, lack of hotkeys, UI that is not as responsive as it should be, drag and drop that works most of the time. To be fair, in these five years browsers and GMail UI improved tremendously. It was rational decision to trade all these for simplicity of the UI.\n","title":"Better GMail than GMail","type":"post"},{"content":" 1) make sure the DNS works # sudo vi /etc/resolv.conf cat /etc/resolv.conf nameserver 208.67.222.222 nameserver 208.67.220.220 nameserver 192.168.16.1 2) check that you have ntpd installed # cat /etc/ntp.conf\n3) make it work in all # /sbin/chkconfig --list | grep ntpd sudo /sbin/chkconfig --level 2345 ntpd on 4) Initial sync # sudo /usr/sbin/ntpdate pool.ntp.org\n5) Start service / restart # sudo /sbin/service ntpd start\n","date":"February 3, 2011","externalUrl":null,"permalink":"/posts/2011-02-03-linux-time/","section":"Posts","summary":"1) make sure the DNS works # sudo vi /etc/resolv.conf cat /etc/resolv.conf nameserver 208.67.222.222 nameserver 208.67.220.220 nameserver 192.168.16.1 2) check that you have ntpd installed # cat /etc/ntp.conf\n3) make it work in all # /sbin/chkconfig --list | grep ntpd sudo /sbin/chkconfig --level 2345 ntpd on 4) Initial sync # sudo /usr/sbin/ntpdate pool.ntp.org\n","title":"Configuring permanent time updates for Linux","type":"post"},{"content":"I have came to a conclusion that I do have too much stuff in my life.\nToo much and too little and the same time.\nToo much information. Too many interruptions and distractions. Too little time to think.\nToo much consumption of information and not enough time to process it and do anything meaningful with it - learn from it or create something new.\nThe only way how to get out of the self-digged hole is to start cutting.\nOne of the big sources of distraction and cause of many pointless hours spent on Web is Twitter.\nI was using Twitter mostly as filter: by following people with similar interest, trying to curate the content \"out there\".\nIt worked to a certain degree - and I indeed discovered some interesting pieces of information I would miss otherwise.\nThe real questions I have to ask are: did these discoveries justify the time spent reading through pointless tweets (big portion of twittersphere) ? The answer is no. What would I miss by not finding them ? The answer is - not much, really. What difference did not missing them make in the\nlong run ? And the final answer is None.\nIt is very hard to say something that matters in 160 characters. Some people can do it, I am not one of them.\nSo after few years of being on Twitter I am deleting my Twitter account today.\nBye bye Twitter. I will try not to miss you. And I am sure you will not miss me.\n","date":"January 30, 2011","externalUrl":null,"permalink":"/posts/2011-01-30-bye-bye-twitter/","section":"Posts","summary":"I have came to a conclusion that I do have too much stuff in my life.\nToo much and too little and the same time.\nToo much information. Too many interruptions and distractions. Too little time to think.\nToo much consumption of information and not enough time to process it and do anything meaningful with it - learn from it or create something new.\nThe only way how to get out of the self-digged hole is to start cutting.\n","title":"Bye bye Twitter","type":"post"},{"content":"I have find new podcast that I want to share with you. It is called \"This Developer's Life\" and is produced by well known digerati Scott Hanselman and Rob Conery.\nI listen to a lot of podcasts, about 50 % of them produced by Leo Laporte's TWIT Network (This Week in Tech, Macbreak, This Week in Google, FLOSS Weekly and occasional Security Now).\nWhat I like about Leo's network is professionalism of audio production, usually good and interesting panel with topics that are worth listening to. Few other podcasts come even close to the TWIT level of perfection.\nExcept this one which is much better. Not necessarily from audio or production point of view - although they are both very good. This developers life goes way beyond what Twit does. It is not a dialog of few interesting geeks, it is story. Story nicely designed, well crafted, interwoven with really good music. It changes from dialog to story with commentaries, but keeps you interested. An episode usually\nfocuses on single theme and contains several stories. Topics are not technology, but the area where technology overlaps with life: motivation, audacity, highs and lows of programming career\nGreat selection of guests, including cybercelebrities such as John Resig or Miguel de Icaza.\nI almost never listen to a podcast episode twice. For this one, I do.\nHighly recommended.\nhttp://thisdeveloperslife.com/\n","date":"November 24, 2010","externalUrl":null,"permalink":"/posts/2010-11-24-podcast-recommendation/","section":"Posts","summary":"I have find new podcast that I want to share with you. It is called \"This Developer's Life\" and is produced by well known digerati Scott Hanselman and Rob Conery.\nI listen to a lot of podcasts, about 50 % of them produced by Leo Laporte's TWIT Network (This Week in Tech, Macbreak, This Week in Google, FLOSS Weekly and occasional Security Now).\nWhat I like about Leo's network is professionalism of audio production, usually good and interesting panel with topics that are worth listening to. Few other podcasts come even close to the TWIT level of perfection.\n","title":"Podcast recommendation","type":"post"},{"content":"The post is on corporate blog - http://blog.thinkwrap.com/blog/2010/2/24/jsp-compiler-configuration-in-jboss-42x-for-atg.html\n","date":"February 24, 2010","externalUrl":null,"permalink":"/posts/2010-02-24-jsp-compiler-configuration-in-jboss-4-2-x-for-atg/","section":"Posts","summary":"The post is on corporate blog - http://blog.thinkwrap.com/blog/2010/2/24/jsp-compiler-configuration-in-jboss-42x-for-atg.html\n","title":"JSP compiler configuration in JBoss 4.2.x for ATG","type":"post"},{"content":"As regular listener to multiple TWIT Network podcasts (This Week In tech, Macbreak Weekly, This Week in Google, Free Libre Opensource Software, Security Now, Windows Weekly) I am very much aware of all the advertisers that keep Leo and the gang in business and make the podcast's stream going. I have even acted upon several of the ads: we are customer of SquareSpace.com (the corporate blog runs on that platform), GoToMeeting is regular part of day-to-day business - we have several accounts and use it regularly for meetings. I would use GoToMyPC if I had any need to go to a PC :-). I bought Spinrite, although I used it only once over last 3 years.\nStrangely enough, the only advertiser I do not see of trying out is Audible - not because I would not like their product offering, quite the opposite. I simply have have absolutely no time for more content in my life: TWIT plus few additional podcasts, Apple TV and ZIP.ca give me way more that I have time to consume. I have no intention of buying Mustang with Sync - my selection of gadgets purchased as part midlife crisis is strictly limited to shiny objects featuring either Apple logo or an IP address, ideally both. But back to point: I feel I have done my share in keeping TWIT in business and do not really want and have to listen to same adds 3-6 times every week.\nFortunately, the adds are not too annoying to justify drastic measures and additional inconvenience - such editing them out from MP3. I have to give Leo credit for being sensitive in his ad selection - except Mustang, which I find to be least in line with TWIT audience - most products were pretty good.\nI found very simple solution that surprised me with completely unexpected side benefit. Whenever Leo goes to an ad (and J.C. Dvorak disappears to baste meat), I turn down the volume to 0 for 2-3 minutes. Just turn the volume off and focus on driving, walking or whatever I am doing. I do not plan, evaluate, program or think about anything, only focus on the current moment and feel whatever is happening right now. I found this being an excellent stress relieve and instead of being annoyed by the ads, I actually started to look forward to them. I do not necessarily subscribe to *all* that New Age hype about being in the present moment, but finding an opportunity few times a day just stop and focus on whatever is happening right now, however simple or mundane that activity is, has its benefits. And there is always something going on: at minimum, you are always breathing.\nTherefore, Leo and all Twits - thanks for all the adds. Ignoring them in a creative way is actually very healthy.\n","date":"January 26, 2010","externalUrl":null,"permalink":"/posts/2010-01-26-thanks-for-all-the-adds/","section":"Posts","summary":"As regular listener to multiple TWIT Network podcasts (This Week In tech, Macbreak Weekly, This Week in Google, Free Libre Opensource Software, Security Now, Windows Weekly) I am very much aware of all the advertisers that keep Leo and the gang in business and make the podcast's stream going. I have even acted upon several of the ads: we are customer of SquareSpace.com (the corporate blog runs on that platform), GoToMeeting is regular part of day-to-day business - we have several accounts and use it regularly for meetings. I would use GoToMyPC if I had any need to go to a PC :-). I bought Spinrite, although I used it only once over last 3 years.\n","title":"Thanks for all the adds","type":"post"},{"content":"It has been one month now that I started to use Windows 7 based Dell Vostro 1320 notebook on daily basis. The hardware parameters of this little thing are: Core 2 Duo 2.26, 500 GB HDD, 8 GB of RAM, 13\" screen, Windows 7 Professional (64 bit of course, how else with all that RAM). All this with 3 year next business day warranty for about $1400 CAD - not bad deal at all.\nReason of going bi-OS was need to run different configurations of ATG suite, consisting of 3-4 instances of JBoss (each with 1-2 GB of RAM) and the database server at the same time. The database server is quite often SQL Server which as we know does not really run on anything else but Windows. The performance penalty of using VM on notebook is too large so I had to go native. Alternative arrangement - Bootcamp on new Macbook Pro would be way too expensive - just price of additional RAM and Windows would be about $800, all this with sharing 500 GB between 2 OS-es, so I took the chance to use Windows on PC grade hardware.\nFirst impression on OS front: I like it. It is definitely the least annoying OS made in Redmond. Ever.\nMicrosoft picked good features to copy from OS-X - the dock is finally something that works. I really like the \"compatibility mode\" - it has saved me few times already when installing software either too old or too paranoid to go ahead without detecting XP. Combination of explicit and implicit restore points also worked very well for me: it is nice relief after years in running installers with the feeling \"if this fails, I am screwed and nothing but completely reinstall will get registry back to same state again\".\nWhat also works much better than any windows is waking up and jumping networks. Wifi is quite reliable and security zones make sense. Kudos to Microsoft for getting it (finally) right.\nAll these observations are made while I am using Windows 7 in parallel with Snow Leopard. I have expected it to be much more annoying and uncomfortable going back and forth. The only thing that still drives me crazy is the Ctrl-versus-Command key schizophrenia. I really wish there was a way how to make this be consistent.\nOn hardware side, I am less enthusiastic. The form factor and portability of beefed up notebook is the best thing I am really happy about. The rest is OK. Keyboard is OK, but not great. The trackpad drives me crazy with being much smaller that it could be and not allowing multi-finger scrolls. Screen is OK but not as great as the MBP equivalent. DVD drive often does not close and the convenient buttons for media play should provide some form of tactile feedback.\nI found that ideal mode of using the Vostro is to switch it on, put is somewhere within reach of WiFi network and access the desktop using remote desktop client from a Mac. This way I have access to really good keyboard and trackpad as well as the option of using all the Mac only software I need in addition to Windows: like Things, TextMate, OmniGraffle. The cloud based services (Google Docs, DropBox, Evernote) take care of keeping things that need to be in sync in sync. Best of both worlds.\n","date":"January 25, 2010","externalUrl":null,"permalink":"/posts/2010-01-25-one-month-with-windows-7/","section":"Posts","summary":"It has been one month now that I started to use Windows 7 based Dell Vostro 1320 notebook on daily basis. The hardware parameters of this little thing are: Core 2 Duo 2.26, 500 GB HDD, 8 GB of RAM, 13\" screen, Windows 7 Professional (64 bit of course, how else with all that RAM). All this with 3 year next business day warranty for about $1400 CAD - not bad deal at all.\n","title":"One month with Windows 7","type":"post"},{"content":"","date":"January 25, 2010","externalUrl":null,"permalink":"/tags/windows/","section":"Tags","summary":"","title":"Windows","type":"tags"},{"content":"\nTo be fair, the book is to appear in March 2010, so most likely the cover image is not ready yet. But I found lack of images for book whose main point is to make explanation illustrated quite ironical :-).\n","date":"January 24, 2010","externalUrl":null,"permalink":"/posts/2010-01-24-unintended-coincidence/","section":"Posts","summary":"\nTo be fair, the book is to appear in March 2010, so most likely the cover image is not ready yet. But I found lack of images for book whose main point is to make explanation illustrated quite ironical :-).\n","title":"Unintended coincidence","type":"post"},{"content":"Few weeks ago, first Foursquare application and then my favorite RunKeeper app started to fail. The symptoms were simple:\n1) attempt to start\n2) wait for for 2-10 seconds\n3) exit\nAnalysis of the crash logs did not reveal anything obvious (see ~/Library/Logs/CrashReporter/MobileDevice/NAME:\nProcess: foursquare [374] Path: /var/mobile/Applications/7F37347B-......1663AA5/foursquare.app/foursquare Identifier: foursquare Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2009-12-22 12:39:11.260 -0500 OS Version: iPhone OS 3.1.2 (7D11) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x20294628 Crashed Thread: 0\u0026lt; Thread 0 Crashed: 0 libobjc.A.dylib 0x32668ecc 0x32665000 + 16076 1 CoreFoundation 0x32d83d6a 0x32d4d000 + 224618 2 CoreFoundation 0x32d4fc28 0x32d4d000 + 11304\u0026lt;/p\u0026gt; What helped was to delete both applications from the phone, including data and let the iTunes install it back. No data is lost, because both services are cloud based - only minor inconvenience was to re-enter login information.\nSo, Nael - I am back in the game and cannot wait to claim back mayorships for all places I have been ousted :-)\n","date":"January 11, 2010","externalUrl":null,"permalink":"/posts/2010-01-11-cure-for-crashing-foursquare-and-runkeeper-on-iphone/","section":"Posts","summary":"Few weeks ago, first Foursquare application and then my favorite RunKeeper app started to fail. The symptoms were simple:\n1) attempt to start\n2) wait for for 2-10 seconds\n3) exit\nAnalysis of the crash logs did not reveal anything obvious (see ~/Library/Logs/CrashReporter/MobileDevice/NAME:\nProcess: foursquare [374] Path: /var/mobile/Applications/7F37347B-......1663AA5/foursquare.app/foursquare Identifier: foursquare Version: ??? (???) Code Type: ARM (Native) Parent Process: launchd [1] Date/Time: 2009-12-22 12:39:11.260 -0500 OS Version: iPhone OS 3.1.2 (7D11) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x20294628 Crashed Thread: 0\u003c Thread 0 Crashed: 0 libobjc.A.dylib 0x32668ecc 0x32665000 + 16076 1 CoreFoundation 0x32d83d6a 0x32d4d000 + 224618 2 CoreFoundation 0x32d4fc28 0x32d4d000 + 11304\u003c/p\u003e What helped was to delete both applications from the phone, including data and let the iTunes install it back. No data is lost, because both services are cloud based - only minor inconvenience was to re-enter login information.\n","title":"Cure for crashing FourSquare and RunKeeper on iPhone","type":"post"},{"content":"Some companies just do not get it.\nIt starts with an email, like this one:\nBy coincidence, you are on project that has the CRM component so you decide to check it out and click on link. After all, it is free, right, so why wouldn't you ?\nThe catch is that it is not free at all. Without realizing it, you have already made your first payment, by doing the sender a favor: as we know, clicking on a link in email is definitely not a good idea and recommended behaviour, unless you know the sender and trust the sender. Which - in this case - you have absolutely no reason to.\nThe link that promises to lead to the free whitepaper, ends up here:\nSo the \"free whitepaper\" is not quite free and you just continue paying - with most precious currency: your time. First you need to spend the 10-15 minutes to fill out the lengthy form. Then another chunk of your time to actually read what you downloaded, just to find out that (in 9 out of 10 cases) it is useless, fluffy marketing material. If you pay attention to fine print below, you'll find out that you have just subscribed to unknown number of similar spammy mailing lists and will be receiving many more offers for \"free\" stuff. Add more payments: time spent on weeding them out from Inbox for the rest of the email address' lifetime ... because majority of Unsubscribe links are (similar to unicorns) purely mythical constructs.\nThis behaviour is so much last century and comes from today completely invalid assumption: that information is something precious, valuable that needs to be protected, guarded and given only for exchange for your privacy. In today's world, there is abundance of information that competes for readers attention. Rather then asking for anything upfront just to gain access, the authors should be happy and honored that in the world of so many options, somebody actually wants to invest time and effort to get more familiar with their product or service or whatever are they selling. Because they are selling - the only reason for the form-guarded \"free\" stuff is to sell, either by using the content in question or by following up. After all, they have all information to reach you ...\nI am not against selling or marketing - I just want the sellers to be honest about it. If you really want to collect any information for follow up, how about at minimum provide at least a preview of what the information is about. All respected sellers of eBooks do that - give you at minimum free chapter and TOC as free (I mean *really* free) download. This seems to be such easy and obvious thing, that I am surprised that even respectable companies (such as Citrix in this case) go for this ineffective trickery just to squeeze out contact information from possible audience. It is so easy to create disposable email or use services like http://10minutemail.com/ ...\nBut much easier than using self-destroying email is simply click on next search result link. Why would one expect to gain anything useful from whitepaper produced by company that does not get the basics ?\n","date":"January 5, 2010","externalUrl":null,"permalink":"/posts/2010-01-05-attention-is-new-currency/","section":"Posts","summary":"Some companies just do not get it.\nIt starts with an email, like this one:\nBy coincidence, you are on project that has the CRM component so you decide to check it out and click on link. After all, it is free, right, so why wouldn't you ?\nThe catch is that it is not free at all. Without realizing it, you have already made your first payment, by doing the sender a favor: as we know, clicking on a link in email is definitely not a good idea and recommended behaviour, unless you know the sender and trust the sender. Which - in this case - you have absolutely no reason to.\n","title":"Attention is new currency","type":"post"},{"content":"This is reloaded version of my previous blog - or continuation of the fork.\nFirst thing to start is to explain why did I do something quite contra-productive as relocate the blog and loose all the audience - however small it could have been.\nIt would seem that I like restarts and things reloaded. I did pick a new country to become new home for me and my family (if emigration is not a restart, what else is ?). Back in 2004 we have started Thinknostic to be \"Montage Reloaded\" - a new incarnation of the company I worked for before and liked it a lot. The same story repeats with blogging.\nWhen I started blogging back in 2006, it was Thinknostic second year and we started to really grow: we got our own space beyond small sales office in downtown we have had before, built some serious hardware infrastructure, employee numbers started to go into two digit territory and we landed our first 1 M$+ project. My blog at http://thinkwrap.wordpress.com/ was our unofficial presence in the social space. In 2006 I picked the login and account name \"thinkwrap\", because it was - at that time - a word that kind-of expressed the approach we were using: something between methodology, best practices and a toolset.\nIn the three years, the same word ThinkWrap was selected as the new brand when Thinknostic in Ottawa and Pentura Solutions in Toronto (both \"second life\" companies of Montage origin) merged. Now suddenly, with \"thinkwrap\" in URL, my blog became whole lot more company-bound that I wanted. As everybody can see on dropping rate of contributions, I found pretty hard to post. I was never quite sure whether I really want to present my personal opinion to appear under ThinkWrap brand as something that the company would be saying. Even worse, now we were several times the size as before, with headcount of about 50 - who was I to speak for all these people, when there were so many smarter, more talented and more experienced than myself ?\nAs result, the whole blog thing came to a big halt - no posts for over 6 months. The only solution I could come up with was restart. Thus, a new, real corporate blog was created that is way more than single guy's opinion. I am one of the contributors, meaning that you will find posts by myself but also by Nael, Milos, Mike and few more great and talented guys we are happy to have as part of the ThinkWrap. And more will certainly come. See for yourself at http://blog.thinkwrap.com/.\nFor my personal stuff, I have exported and reimported the content into different WordPress blog and hooked it under domain that clearly indicates that it is my personal blog and personal opinion. Occasionally, I may decide to crosspost some to corporate blog as well, but most of my opinions, suggestions, rants, jokes, book recommendations and crazy ideas will not go beyond this ones :-).\nSo, I have now new place that completes my virtual existence. You can also find me on Twitter and Facebook (albeit I try hard to keep my Facebook friends to be subset of people I did meet in real life).\nHave a good rest of the year and - as my German speaking friends would say: \"Einen guten Rutsch\"\n","date":"December 30, 2009","externalUrl":null,"permalink":"/posts/2009-12-30-blog-reloade/","section":"Posts","summary":"This is reloaded version of my previous blog - or continuation of the fork.\nFirst thing to start is to explain why did I do something quite contra-productive as relocate the blog and loose all the audience - however small it could have been.\nIt would seem that I like restarts and things reloaded. I did pick a new country to become new home for me and my family (if emigration is not a restart, what else is ?). Back in 2004 we have started Thinknostic to be \"Montage Reloaded\" - a new incarnation of the company I worked for before and liked it a lot. The same story repeats with blogging.\n","title":"Here we go again","type":"post"},{"content":"You know the drill: open browser, new tab, type 'www.facebook.com' and in moment you can see who of your online buddies is up to something interesting. This is exactly what I did. Only I did not end up in well known Facebook page, but on something really fishy:\nThis is definitely NOT facebook. How come I ended up on 'quiz.us' site when I typed in www.facebook.com. Or did I ? Let's do it again:\nDo you see the problem ? It is the URL. Unlike real www.facebook.com, it is www.facebok.com. Easy to overlook. Modern browsers make our life easier by suggesting domain named. And 'facebok' comes in alphabet before 'facebook'. Which is more than enough to catch many lazy users, like myself.\nThese guys - quiz.us - were obviously not Facebook related and judging by their pages behaviour, their were up to no good.\nAfter clicking on 'Skip this offer' it opened up another window, did several redirects and reloads.\nThe new window tried really hard not to allowed to be closed easily. Annoying pop-ups, deliberate language to confuse OK and Cancel, more pop-ups.\nThe \"company\" is registered in Florida, US, as the Who Is told, it is Named \"Moniker Online Services\" with technical contact 'Moniker Privacy Services'. Not sure what they really are, but certainly what their pages tries to achieve is a disservice to anybody's privacy.\nLesson learned: use trusted bookmarks, do not click on combo box suggestions.\nAt least not until there are so many kinds of filthy internet vermin around. Facebook atracts so many new users that are not very experienced in dirty tricks the spammers, phishers and hackers use. Spread the word and help your friends to avoid pages and companies in business of phishing and deception.\n","date":"July 24, 2009","externalUrl":null,"permalink":"/posts/2009-07-24-facebook-domain-type-in-hack/","section":"Posts","summary":"You know the drill: open browser, new tab, type 'www.facebook.com' and in moment you can see who of your online buddies is up to something interesting. This is exactly what I did. Only I did not end up in well known Facebook page, but on something really fishy:\nThis is definitely NOT facebook. How come I ended up on 'quiz.us' site when I typed in www.facebook.com. Or did I ? Let's do it again:\n","title":"Facebook domain type-in hack","type":"post"},{"content":"I stumbled upon this pretty nice little application or service - depends how you see it. It is called reQall (obviously would have been recall, but recall.com as every good domain is taken.\nWhat it does is that allows you to set a reminder in the future to do something - at given time and date: buy X, call Y, do Z. Nothing to earth-shattering about that.\nWhat is neat is the way how you do it. Actually, many ways:\n1) old fashioned: use web site, enter reminder. Just type text and reQall will extract both activity (buy / call etc) as well as date and place it in appropriate category. And when time comes you will be notified: either via email, or via SMS or even by some of the IM services. Currently supported are Yahoo, Google Talk, Jabber and AIM.\n2) modern: use iPhone app to type in reminder. Same goodies as wit web, only - unlike Web - you have the phone with you available quickly at the moment when you actually need to remember something.\n3) modern AND cool: use the same iPhone app, and speak up to 30 second message. It will be converted to text and then analyzed same way as typed text. I am not sure whether it is automated translation or some poor fellas in third world country and listening and typing it in. The understanding is VERY good. It even handles non-native speakers of English with strong accents (like myself) with surprising success rate. I had occasionally some question marks indicating that Person's name or local place was not understood. For this occasion, you can always listen to your own audio ;-)\nYou can also subscribe to daily jots that sums up your upcoming events.\nBest of all: it is a free service. There is a pro version for $2.99 a month which adds some nice features. I am seriously considering to go for Pro just to make sure they can survive - as long as I find that I use it more than 1-2 times a week, I am in.\nGive it a try, it may be worth one small chai latte a month.\n","date":"May 23, 2009","externalUrl":null,"permalink":"/posts/2009-05-23-forget-me-not-web2-0-edition/","section":"Posts","summary":"I stumbled upon this pretty nice little application or service - depends how you see it. It is called reQall (obviously would have been recall, but recall.com as every good domain is taken.\nWhat it does is that allows you to set a reminder in the future to do something - at given time and date: buy X, call Y, do Z. Nothing to earth-shattering about that.\nWhat is neat is the way how you do it. Actually, many ways:\n","title":"Forget me not, Web2.0 edition","type":"post"},{"content":"","date":"May 23, 2009","externalUrl":null,"permalink":"/tags/webapp/","section":"Tags","summary":"","title":"Webapp","type":"tags"},{"content":"From the author that wrote Tipping point (on my reading list) as well as Blink - which I listened to but found rather controversial. I was very curious what will this one be about.\nThe book is about success and people that managed to achieve extraordinary results. It touches several topics, I will pick three of them that I found most interesting. It starts with interesting observation - if you look at the MONTH of the birth of junior NHL hockey players, you'll discover that over 50% of them was born between January and April. Certainly not anything like normal distribution. The point is that cutoff-date for signing up children into hockey training in Canada is January 1st. At the age when this happens (5-6 years), kid born in January has significant physical and mental advantage against kid born in November or December. As result, the early born children perform better in their category, and as result they are more likely to make the selection between the talented and perspective. Those selected get much more opportunities to play and practice, which causes them being really better players than late born ones - a kind of self fulfilling prophecy. As result - if your kids are born after August, better reconsider the NHL dreams. If you believe what M.G. is saying, I mean.\nThis topic leads to the second big theme that made me think really deep - the 10'000 hours rule. M.G. claims that in order to be really good at pretty much anything, you have to spend about 10000 hour practicing. Among many examples he mentions Bill Joy and Bill Gates with their early years almost unlimited access to the computer, Beatles during their concerts in Germany and several others. If this is really true, it has quite serious implications for our profession.\nThe third is very interesting comparison about how differences between eastern and western agriculture - growing rice in rice paddies vs western farms has implications on the work ethic and math skills of the population.\nHe also explores many other quite interesting subjects - the ethnic theory of plane crashes (exploring how \"power distance\" in particular cultures impacts the communication between captain of the aircraft and first officers), why are merger and acquisition law firms pretty much of the same ethnic origin and also claims that the US schools are basically OK, it's the parents that do not do enough for their kids education. Hmm.\nTo sum it up, it was good and interesting read. Certain parts could be shorter - sometimes it unnecessarily re-iterates the same message, but it is certainly very intellectually stimulating and thought provoking book.\nAlthough I am a bit skeptical with respect to some of his conclusions or input data - as we know, if we properly select data set it is easy to prove pretty much anything ;-), I am very glad I picked it - the point of view and approach presented is absolutely worth the time and money spent.\nThe destilled message of the book can a bit demotivating to those who believe that talent and hard work will always pay back: even if you have all the talent and put in all 10K hours, you still need to have that final ingredients of success - such as being born in January for NHL hockey player and a bit of luck. Also those who believe that the succesful people are just lucky or born with silverspoon may be disappointed that all that does not work without the really hard work and practice.\nUnless you belong to one of the above groups - recommended. And if you do - you should definitely read it !\n","date":"May 20, 2009","externalUrl":null,"permalink":"/posts/2009-05-20-book-recommendation-outliers-by-malcolm-caldwell/","section":"Posts","summary":"From the author that wrote Tipping point (on my reading list) as well as Blink - which I listened to but found rather controversial. I was very curious what will this one be about.\nThe book is about success and people that managed to achieve extraordinary results. It touches several topics, I will pick three of them that I found most interesting. It starts with interesting observation - if you look at the MONTH of the birth of junior NHL hockey players, you'll discover that over 50% of them was born between January and April. Certainly not anything like normal distribution. The point is that cutoff-date for signing up children into hockey training in Canada is January 1st. At the age when this happens (5-6 years), kid born in January has significant physical and mental advantage against kid born in November or December. As result, the early born children perform better in their category, and as result they are more likely to make the selection between the talented and perspective. Those selected get much more opportunities to play and practice, which causes them being really better players than late born ones - a kind of self fulfilling prophecy. As result - if your kids are born after August, better reconsider the NHL dreams. If you believe what M.G. is saying, I mean.\n","title":"Book recommendation: Outliers by Malcolm Caldwell","type":"post"},{"content":"","date":"May 20, 2009","externalUrl":null,"permalink":"/tags/books/","section":"Tags","summary":"","title":"Books","type":"tags"},{"content":"This is public answer to all who were asking why is my blog so badly neglected. Short answer is: It is because I am pretty active elsewhere and did not really find any additional time to allocate. If you are busy person, now you know, see ya later. If you are curious what elsewhere means, read on.\nLast year and before, blogosphere and this blog was *only* part of the social networking space I was paying attention to. Since about 3-4 months I started to really pay attention to Facebook. I originally joined to find out what my son and couple of friends are up to and somehow I started to see value in this channel of communication. Recently, even my nephews and children of a very good friend that moved from Ottawa to Europe. So Facebook became the \"generation bridge\" and channel for stuff out of workspace.\nWith iPhoto'09 excellent Web integration plugin it is so easy to share picture that I could not resists and uploaded couple of albums :-) - like this one.\nAbout month ago, I fell for Twitter. I had account on Twitter for several months, but did not really get it. Actually I pretty much hated Twitter being to most discussed topic on Twit. It was actually one of our owns - Nael - that caused\nme to reconsider, and I am glad I did. Speaking of Nael - if you are interested in social networks from developer's point of view, SEO and location based services, follow Nael on Twitter. He also runs very good blog.\nAgain, Twitter is excellent addition - it covers the niche that is too low level or too short lived to be Facebook Worthy. With clients like TweetDeck I can even update both Facebook and Twitter, if I decide to do so. Different people use it for different purposes, for me it is replacement for news and RSS, filtered by the people I have selected combined with (filtered) lifestream log of events and ideas.\nFor the stuff that is really work related, we have two additional social network and collaboration tools, that limited to the company employees. One is Yammer - a private version of Twitter with very nice UI. Second is Wiki - we use Atlassian's excellent product Confluence. This is location for everything that is either client confidential, covered by NDA or has intellectual property value. As it happens, lots of information, e.g. related to ATG development goes through and ends up in these channels.\nI have also reluctantly returned back to log on into MSN Messenger and Skype. I generally find them quite disruptive and leave them off unless I have a immediate need to communicate. Which I do. The project I am working on has contributors all over the place - Toronto, Halifax, Cape Breton, Ottawa - and MSN is the \"bloodline\" of the project communication.\nSo if you want to keep in touch, do not rely solely on blog. You can see me on Facebook (search for Miro Adamy). If somebody I never heard of sends me a friend request I often ignore it, but if you mention blog, I will not. Or you can follow me on Twitter - the nick is miroadamy. For that you do not even need permission :-).\nThe only way how to follow me on Yammer, you must join ThinkWrap Solutions :-). The good news is that we may be needing just somebody like you - there are couple of really interesting projects starting soon, and besides, we are always looking for great people. Send resume to careers at thinkwrap dot com and you will hear back from us.\nPlease note - no overseas or teleworking and no agencies - you must be legally able to work in Canada and live either in Ottawa or Toronto (Mississauga).\n","date":"May 17, 2009","externalUrl":null,"permalink":"/posts/2009-05-17-lost-in-the-social-networks/","section":"Posts","summary":"This is public answer to all who were asking why is my blog so badly neglected. Short answer is: It is because I am pretty active elsewhere and did not really find any additional time to allocate. If you are busy person, now you know, see ya later. If you are curious what elsewhere means, read on.\nLast year and before, blogosphere and this blog was *only* part of the social networking space I was paying attention to. Since about 3-4 months I started to really pay attention to Facebook. I originally joined to find out what my son and couple of friends are up to and somehow I started to see value in this channel of communication. Recently, even my nephews and children of a very good friend that moved from Ottawa to Europe. So Facebook became the \"generation bridge\" and channel for stuff out of workspace.\n","title":"Lost in the social networks","type":"post"},{"content":"I was happy user of the iWork Suite 08 since I moved to OS-X. It somehow better matches the way I am thinking and does much better job than Office to get me from idea to acceptable looking rendering of that idea in the form of document, spreadsheet or presentation.\nIn past two month I was involved much more interaction with the requirements, business analysis and project management part of the process. Which inevitably means much higher exposure to documents creation, collaboration and exchange. iWork gives you reasonably good compatibility with Office document formats, which means that you can easily import almost every Office document modify it and export it back so that Windows user will see almost all of your changes. Almost everything will be just fine. Unfortunately, almost is not the same as everything: it often breaks fine details of formatting, reviewer comments and does not really work for more complicated Excel spreadsheets. Especially those spreadsheets which project manager-ish people so love to create.\nI tried to use OpenOffice/NeoOffice which suffers from the same malady. It spoils different set of features than iWorks, quite often works well, but it cannot be trusted. On top of that, it just does not feel right and is kinda ugly.\nSo I had to take a deep breath and installed Office 2008. After few weeks, here is my impression and very brief comparison of all three mentioned suites.\nWith Office 2008, I was not having very high expectations regarding user experience on Mac and I have to report that Microsoft did not disappoint. I indeed was not too great experience, starting with installation.\nOffice 2008 contains 4 products. I absolutely wanted Word and Excel, was not quite sure about Powerpoint (because Keynote is sooo much better), and certainly had zero interest in Entourage and Microsoft Messenger.\nGuess what: Microsoft installer, as many times before, knew better what I want and did not give me a chance. All questions asked were related to what Microsoft needs to know (serial number), with little regard for users interest. It also installed whole bunch of fonts, which I did not really want - but I guess to provide 100 % compatibility with Windows, it may be a good idea to include same set of fonts as Windows office has.\nAfter installation, Office 2008 works reasonably well. Minor annoyance is start taking forever - I guess it is because (unlike under XP/Vista) OS-X does not preload shared components (and does not eat up memory just to make Office appear start snappier). As soon as any Office application is running, I have occasionally seen weird behaviour when switching between windows (note lowercase 'w') and does not play nice with Spaces. Sometimes scrolling forgets to redraw screen in word and you have to minimize/restore to get back to readable text. And it is generally quite slow even on very fast and powerful machine.\nWith respect to the main motivation for getting Office - seamless document compatibility - that problem appears to be solved. So far I have not seen anything that would be distorted or deleted just because I touched the file on the Mac. Only exception is Excel - Office 2008 does not support VBA macros, so your mileage with more advanced spreadsheets may vary.\nShould I mark my experience with Office 2008 using school grades, it would be:\n- installation: C\n- user experience: B-\n- compatibility with Windows Office: B+\n- price/performance ratio: D\n- overall: B-\nFor iWorks'08 it would be:\n- installation: B (if I recall correctly, it was OK, but required installer).\n- user experience: B+\n- compatibility with Windows Office: C\n- price/performance ratio: A-\n- overall: B\nFor NeoOffice:\n- installation: C-\n- user experience: C-\n- compatibility with Windows Office: C+\n- price/performance ratio: A\n- overall: C+\nRecommendation:\nIf you are working on Mac as part of a team that collaborates using Office documents, you most likely need Office 2008. Unfortunately the only office package that comes very close to be compatible with Office 2003 and Office 2007 is Office 2008.\nIf you value user experience, aesthetics and are OK with mostly one-way conversions between Windows Office, you will find iWork provides excellent value and will make you feel at home. If you never have to exchange documents with Windows world, enjoy it - we all who have to do it daily are green with envy.\nIf you for economic or ideological reasons refuse to pay for software (or only for software made by certain companies ;-)) - or if you require compatibility with Linux based office, you have no other choice than NeoOffice or OpenOffice. The first one looks considerably better on OS-X - although still not quite right.\n","date":"April 28, 2009","externalUrl":null,"permalink":"/posts/2009-04-28-microsoft-office-2008-vs-neooffice-vs-iworks08/","section":"Posts","summary":"I was happy user of the iWork Suite 08 since I moved to OS-X. It somehow better matches the way I am thinking and does much better job than Office to get me from idea to acceptable looking rendering of that idea in the form of document, spreadsheet or presentation.\nIn past two month I was involved much more interaction with the requirements, business analysis and project management part of the process. Which inevitably means much higher exposure to documents creation, collaboration and exchange. iWork gives you reasonably good compatibility with Office document formats, which means that you can easily import almost every Office document modify it and export it back so that Windows user will see almost all of your changes. Almost everything will be just fine. Unfortunately, almost is not the same as everything: it often breaks fine details of formatting, reviewer comments and does not really work for more complicated Excel spreadsheets. Especially those spreadsheets which project manager-ish people so love to create.\n","title":"Microsoft Office 2008 vs NeoOffice vs iWorks'08","type":"post"},{"content":"The double backup word in the title is not an oversight. If I would be talking about \"almost perfect backup solution\", it would be Time Machine - which has proven, despite it's minor annoyances (see this) to be very unobtrusive and functional. As long as you have Mac and Leopard, of course.\nWhat I am talking about here is second level - an offsite backup, that you may need in case you house burns down, gets flooded or your computer with time machine disk gets stolen. I do not live in tornado valley, earthquake zone and crime rate around Westboro is fairly low even compared to low Canadian levels, but anyway.\nThe product in question is Backblaze and I am happy user since December last year. It is cloud based service, running on (I assume) Amazon S3 and unlike Time Machine it works for all you stuck in Windows world as well. Not available yet for all you brave explorers of multiple universes of Linux, but I guess you would not give up rsync anyway :-).\nAll you need to do is setup a very low profile client that runs in the background and uploads all that was changed. The initial backup can take few weeks, depending on the size of the hard disk.\nIt backups almost everything, except system areas and few excluded file types - like DMG and VMDK (virtual machine volumes). You can define your own exclusions but you cannot un-exclude the default exclusions.\nBackblaze has quite attractive pricing scheme: you pay $5 a month per computer and can backup as much as the pipes between your house and cloud allow you to push up. The price of one venti chai latte is in my books very much worth the good feeling.\nWhen the disaster strikes and you need your files, you do not have to go the slow route and download multi-gigabytes of data. For reasonable fee, Backblaze will send you your data on DVD's or even on USB disk. I hope I will never need that :-). For small recovery you can always access files using Web interface.\nBecause I am curious creature and like to understand how thing work, I was watching its progress for few weeks. Thanks to my curiosity I had several communications with backblaze technical support. I am happy to report that:\na) it exists ! (this is always the case with cloud companies )\nb) it is very fast - I got back response in few hours, one day max\nc) it is very competent and friendly. The person I communicated with knew the product at the deepest technical detail level.\nLast but not least: privacy and security. Many people are concerned about having their data anywhere except on the server in locked office. I trust strong encryption. In addition to using SSL for transfer, Backblaze gives you an option for aditional encryption on client side - before the data leaves your computer it is encrypted with the key only you know. This way you cannot download the data through Web unless you enter the key and not even Backblaze can read your data.\nSo why almost perfect ? There are few minor issues. I would certainly like to have more control (and better UI) for both monitoring and management of the files to be backed up. Either GUI client, or simple way to put a file inside directory that would work as .gitignore. Actualy, for a developer, it would make sense not to backup anything specified in .gitignore or .svnignore or .cvsignore files, because if something is not worth putting to source control, it is not worth backup up either.\nOther are duplicate files: I have on my notebook subset of pictures, podcasts and music from home iMac. Those files are backup up and tranferred twice. With volume, this becomes an annoyance. Backblaze could based on SHA1 recognize the duplicate files within same account and offer option skip those already uploaded - same way how Git stores each blob only once.\nLast issue (which is completely out of Backblaze's control) is your bandwidth. Since I started, I am maxing out my 95 GB transfer limit with Rogers in third consecutive month. Here in Canada, 95GB is max you can get unless you pay for business connection[1] (which is several times the price of \"Extreme plus\"). You have some control over the backup upload speed - you can \"throttle\" the speed and you can also manage schedule (to a limited extend). This may or may not impact you - depending on your bandwidth allocation and size of the data to back up.\nAll summed - definitely recommended.\nDisclaimer: I am not anyhow affiliated to Backblaze product or company. Only reason for this blog is my personal, very positive experience with their product and user support, which I believe deserves to be shared.\n","date":"March 24, 2009","externalUrl":null,"permalink":"/posts/2009-03-24-almost-perfect-backup-backup-solution/","section":"Posts","summary":"The double backup word in the title is not an oversight. If I would be talking about \"almost perfect backup solution\", it would be Time Machine - which has proven, despite it's minor annoyances (see this) to be very unobtrusive and functional. As long as you have Mac and Leopard, of course.\nWhat I am talking about here is second level - an offsite backup, that you may need in case you house burns down, gets flooded or your computer with time machine disk gets stolen. I do not live in tornado valley, earthquake zone and crime rate around Westboro is fairly low even compared to low Canadian levels, but anyway.\n","title":"Almost perfect backup backup solution","type":"post"},{"content":"Since few months I have slowly switched all my online notebooks to Evernote. In case you are not familiar with it, it is a great service. You can clip pieces of Web pages, type in notes, attach documents and multimedia files (pictures, sounds) and store them online to be always available through nicely done Ajaxian Web interface. The notes can be tagged, organized into notebooks and full text searched. One of the killer features is that for uploaded pictures, Evernote will do OCR and include the photographed tex into full text search\nFor each platform there is desktop application that seamlessly synchronizes the on-line notes with local database and also allows create notes using thick client interface with all desktop goodies. If you are iPhone users, make sure you get the free app that allows both access the notes as well as capture notes - textual, pictures or voice notes with the GPS information.\nThe basic service is free and limits you not by storage taken on the servers, but by transfer 40 MB a month, which is a lot unless you do picture notes. The very reasonably priced pro-service increases the monthly transfer quota to 500 MB and gives few more goodies - like PDF and Doc attachments to the notes. I am fairly frequent user and never used more than one half of that amount. To make clipping from the browser easier, Evernote offers Firefox plugin as well as Safari plugin.\nThe Firefox plugin is equipped with the self-update capabilities. And this is why I am posting this: if you have not updated yet, stick to version 3.0.0.128, do NOT upgrade to latest but far from greatest 3.0.0.45382. The latest version of Evernote (3.0.0.45382 as of today) is definitely a step back. Unlike the .128 which clips the selected text nicely into the Web, the .45382 always opens the desktop application and creates note there. This is only annoying and there is no obvious way how to prevent starting desktop client.\nThe real problem is that the captured note contains HTML attachment named 'Firefox clipping.html' and does not show the clipped text in the Evernote desktop client. To see what you clipped you need to open the clipping in the browser. To add insult to the injury, the quality of clipping is dramatically worse than in .128. The layout is all over the place, and result looks much worse. It is hard to tell whether this is caused by clipping or by different way how to display result.\nIf you got to the point of bad surprise after updating, here is how to bring back the version .128:\n- uninstall extension\n- restart Firefox\n- download the previous version of the extension (the .xpi file) from here https://addons.mozilla.org/en-US/firefox/downloads/file/47839/evernote_web_clipper-3.0.0.128-fx+tb.xpi and save it on local disk\n- in Firefox, open the downloaded file and confirm installation\n- restart Firefox\nI hope that somebody at Evernote will recognize that the version .45382 was a bad idea and bring back the clip-to-web capabilities (or at least make it configurable), avoid creation of useless HTML attachments and fix the clipping engine. Until that happens, I will stick with .128.\n","date":"March 22, 2009","externalUrl":null,"permalink":"/posts/2009-03-22-evernote-firefox-plugin-version-30045382-do-not-update/","section":"Posts","summary":"Since few months I have slowly switched all my online notebooks to Evernote. In case you are not familiar with it, it is a great service. You can clip pieces of Web pages, type in notes, attach documents and multimedia files (pictures, sounds) and store them online to be always available through nicely done Ajaxian Web interface. The notes can be tagged, organized into notebooks and full text searched. One of the killer features is that for uploaded pictures, Evernote will do OCR and include the photographed tex into full text search\n","title":"Evernote Firefox plugin version 3.0.0.45382 - do NOT update","type":"post"},{"content":"I first time discovered Ruby back in 2006 (yes, I know, I was late to the game), and immediately fell in love with it. The dynamic nature of the language, the consistency, pure esthaetics and practicality certainly changed the way how I saw software development and programming languages.\nSince that time, I made several attempts to integrate Ruby into my professional life and make it part of the toolbox. It was cool to play with Ruby in my spare time, but I wanted to use it on projects whose main development language/platform was mainly Java. Use it as scripting, glue language. Use it as toolkit language to e.g. generate test data, access databases, convert files, build projects and maybe even build a piece of Web applications (admin apps for example).\nIt never worked. The main problem was availability of the Ruby platform in all environments. While JVM was there by default, Ruby had to be installed and sometimes compiled for the more exotic platforms. And that can be a big deal if you have not full control over the environment - scenario which is pretty much guaranteed in enterprise environment. It is hard to argue with the sysadmin saying \"You want to install that in production just to run scripts ? Why do not you use Perl or Bash or Java that are already there ?\"\nFor a little while I thought that JRuby may be the way. After all - all you need is JVM and JRuby is just another JAR, right ? As Goethe said, grey is all theory and green is the tree of life :-). A language is as good and useful as are components and libraries available. One certainly does not want to write everything from scratch. Libraries in Ruby are Gems and Ruby provides very nice, mature and IMHO superior system for component management to Java JAR's - because it handles different versions of same Gem very well (maybe some day there will be Gem hell after DLL hell and JAR hell ;-) ). Unfortunately, some Gems (by Murphy's law most of the really interested ones) are for performance reasons built as thin Ruby layer around native (written in C) library. And JRuby does support that, making most of the Gems unavailable.\nEven if JRuby had all the gems available, there would still be a problem that the Gem system and Jar system are different and do not quite fit together. Also, from language point of view you certainly can use Java objects in JRuby and vice versa, but doing that makes you feel slightly schizophrenic - what reality am I in? Is this a Java Java class or Ruby Java class ?\nThird problem that I have encountered after coming up with some Web App in Rails is that the deployment model is very different from Java deployment model which myself and people in organizations we work with understand really well. We know how to deploy so that it scales, we know how to monitor and maintain a Java enterprise app. But not a Rails app with all those Mongrels, lighttd's and other creatures :-). This leaves many open questions like \"How do we size hardware for expected load ?\" for which I do not have answers, and judging by well publicized issues with Rails apps scalability, even the best and brightest in Ruby world may not have either - or at least some people say so.\nAbout at the same time I discovered Ruby, I also become aware of the strange Java dialect called Groovy. It sort of tried to do the same thing I hoped to use Ruby for, only from firm within Java environment. The original reason I did not want to look deeper at Groovy was that compared to straight elegance of Ruby, it looked kind of ugly. The Java skeleton was sticking out in wrong places and alltogether it just did not feel as good as Ruby.\nI have to publicly admit I was wrong.\nBeing a Mac user, I have license for going after good looks and white shiny objects, but when it comes to programming languages, the good looks may just not be enough. The reality is the proof.\nDuring last 12 months, we have quietly and very successfully used Groovy components and pieces on three large projects. It fitted perfectly, never running into anyof the issues above.\nThrough these projects, I learned to appreciate the Groovy way, my sense of aesthetics stopped to be offended by certain syntax constructs in Groovy and I even started to like them better than Ruby ones. For example, I am now convinced that Groovy categories are safer and better approach that explicitly alerts programmer about using class extension, than re-opening any class in Ruby (which is still possible in Groovy by assigning closure to member in metaclass). Imagine how confusing it can be for software maintenance when reopening and using happens far apart in the source code.\nBut the most important, the painful realization \" how the heck do I do the XYZ thing in this language ? If I only were coding in Java, it would be so much simpler \" is history with Groovy. Everything that I was used to use in last 12+ years in Java is still there, all the goodies of Jakarta Commons and way more.\nGroovy community seems to be less opinionated, less self-righteous than Rails/Ruby community and more understanding for weird requirements and idiosyncrasies of enterprise environments. Rather than telling you \"you should not want to do this\" and \"DHH thinks it is wrong\", you actually may get a helpful pointer to useful website or blog how to do that stupid thing in Groovy or Java or combination of both. Because you know, when one needs to accomplish something that seems to be wrong and illogical, being told that it is wrong and you should better forget about it does not really help. People who worked with real enterprise system's integration understand, that cost of touching or changing certain systems is so prohibitive that it is out of question and doing the technically wrong thing may right (and only) option for given situation and customer.\nTherefore - bye bye Ruby, Hello Groovy. Next things to embrace and embed will be Grails.\n","date":"March 17, 2009","externalUrl":null,"permalink":"/posts/2009-03-17-bye-bye-ruby-hello-groovy/","section":"Posts","summary":"I first time discovered Ruby back in 2006 (yes, I know, I was late to the game), and immediately fell in love with it. The dynamic nature of the language, the consistency, pure esthaetics and practicality certainly changed the way how I saw software development and programming languages.\nSince that time, I made several attempts to integrate Ruby into my professional life and make it part of the toolbox. It was cool to play with Ruby in my spare time, but I wanted to use it on projects whose main development language/platform was mainly Java. Use it as scripting, glue language. Use it as toolkit language to e.g. generate test data, access databases, convert files, build projects and maybe even build a piece of Web applications (admin apps for example).\n","title":"Bye bye Ruby, hello Groovy","type":"post"},{"content":"In theory, exchanging mainboard on Macbook has no impact because all your data is stored on your harddisk that is untouched. In real life, there are few minor surprises.\nFirst, your MAC address of the network card had changed. This is something you will not notice, unless Murphy's law plays funny game with you, as it did with me. When arriving back to the office, I was able to connect to WiFi network, but the ethernet was stubbornly getting the \"internal IP\" - 169.254.x.x address, which is pretty much useless from connectivity point of view. We are running two separate networks - both NAT-ed, one on WiFi - mainly for guests, other internal. Not getting an IP address did not make any sense: the cable was OK, because other machine worked just fine with same drop/cable. The Ethernet connection was OK, because it worked when assigned IP address manually.\nThe problem was - new MAC address. During last week or so, by playing with virtual machines, I must have allocated all available IP addresses from DHCP server space. The leases are fairly long lived and all slots were taken by either computers around the office or by both running and also now defunct VM's. One of them was still kept reserved for my old and gone MBP's MAC address. Nobody would notice the problem, unless you tried to attach new DHCP based VM or new computer. Lesson learned - if you have problems with internal IP address does not want to go away - check the DHCP server. In home environment, resetting the router mostly helps.\nSecond effect of changed MAC address was that all VMs in Fusion started to ask whether they were moved or copied. Always answer \"moved\", otherwise you VM will get new virtual MAC address generated - which can have impact on your DHCP space (if in bridged mode).\nThird, quite unexpected effect was that Time Machine stopped working, with 'volume cannot be found' message. See e.g. http://www.macfixitforums.com/ubbthreads.php/topics/454151/Time_Machine_can_t_find_backup for more details. It looks like Time Machine is using the MAC address to match the backup volume with the computer it belongs to. Clean solution is to erase backup and start from scratch - or use different disk. Partial solution is a hack - in /Volumes/Time Machine Backup/ locate file that has the MAC address encoded in the name, e.g:\n/Volumes/myTMbackupVolume/.0a1b2c3d4e5f\nGet the new MAC address (from ifconfig) and copy the old cookie file to new cookie file - using the new MAC as name. This made the volume accessible again - with unfortunate effect that pretty much ALL content was considered as unbacked-up and first back up took away over 90 GB of disk space. But at least, the old data was still there, should the need ever occur.\nMaybe this experience will be useful for somebody else - it was quite good learning experience for me.\n","date":"March 4, 2009","externalUrl":null,"permalink":"/posts/2009-03-04-the-aftermath-of-mainboard-change/","section":"Posts","summary":"In theory, exchanging mainboard on Macbook has no impact because all your data is stored on your harddisk that is untouched. In real life, there are few minor surprises.\nFirst, your MAC address of the network card had changed. This is something you will not notice, unless Murphy's law plays funny game with you, as it did with me. When arriving back to the office, I was able to connect to WiFi network, but the ethernet was stubbornly getting the \"internal IP\" - 169.254.x.x address, which is pretty much useless from connectivity point of view. We are running two separate networks - both NAT-ed, one on WiFi - mainly for guests, other internal. Not getting an IP address did not make any sense: the cable was OK, because other machine worked just fine with same drop/cable. The Ethernet connection was OK, because it worked when assigned IP address manually.\n","title":"The aftermath of mainboard change","type":"post"},{"content":"Back in November 2007, when I was buying Macbook Pro, I did order the AppleCare option, which added several hundred dollars to already pretty expensive notebook price. For moment I was tempted to go without it - after all, Apple makes top grade, high quality hardware and considering pretty low failure rate I have seen with my Windows based notebooks between 1998-2006, why to pay more ? Little did I know how much mileage will I get from the extra cost :-(.\nIt is sad to admit, but during last 12 months, I had three major hardware issues with my Macbook Pro. Maybe it was just my bad luck and I got a lemon, but frequency and seriousness of hardware failures makes MBP the least reliable notebook I ever owned.\nIn June 2008, the 250 GB hard drive failed and had to be replaced. Fortunately, I had disk clone and Time Machine brought back everything, so no data was lost. One month ago, one of two 2GB DIMMs died and had to be replaced (to be fair, this one was not original Apple RAM, but cheaper version purchased and installed by authorized service centre). And third issue was failure of graphic card last week - which will likely mean mainboard replacement. The notebook is still in service and I am for 8th day computationally impaired, locked to spare Mac Mini or my home iMac/Macbook, stubbornly refusing using Windows based notebook ...\nSo how would Apple Store help the situation - other than walking in and buying replacement ? As it seems, from discussion with other Mac users, Apple Stores may be the only type of service provider that actually can (and does) keep stock of replacement parts. All other service centres have to take your computer in, detect the cause, order replacement part and wait until is shipped to them from Apple in order to finish the repair. How quickly the part arrives is completely out of their - as well as your - control. It can add up quite a few days to your repair time.\nAnother consequence of no-stock rule is that in this economy, to optimize shipping costs, the parts are most likely to be send in batches. Which means more delay ...\nYes, I know - it could be much worse, one could have to mail the computer somewhere in USA or overseas rather than dropping them to friendly hands of local Apple certified service depot, and have it mailed back to you. Which would add even more time, more cost, and much more chance of additional damage in transport. But on the other hand, if we had Apple Store stocked with replacement parts in the city, with a bit of luck one could walk in, drop the machine and pick it up fixed next day. Would not that be cool ?\nLet's hope that Ottawa's Apple Store is more than just a rumor ...\n","date":"February 23, 2009","externalUrl":null,"permalink":"/posts/2009-02-23-the-myth-of-premium-hardware-or-why-ottawa-needs-apple-store/","section":"Posts","summary":"Back in November 2007, when I was buying Macbook Pro, I did order the AppleCare option, which added several hundred dollars to already pretty expensive notebook price. For moment I was tempted to go without it - after all, Apple makes top grade, high quality hardware and considering pretty low failure rate I have seen with my Windows based notebooks between 1998-2006, why to pay more ? Little did I know how much mileage will I get from the extra cost :-(.\n","title":"The myth of premium hardware or why Ottawa needs Apple Store","type":"post"},{"content":"I was aching to blog about this since December 18th, when our system quietly and gently slipped into public visibility. Marked as Beta (thanks, Google for making this a legitimate way how to go live) it comfortably made it through Christmas shopping season into 2009.\nNow when the site has been announced and mentioned few times in the media, I guess it's OK to mention it here too.\nWhat is \"it\" ? A new, fresh eCommerce site selling music. A lots of really good music. Without any DRM or any other nonsense, as plain good high quality (mostly 320 kps) MP3's. The selection is actually very good - starting from several hundred thousands in December to several few million songs when full catalog is loaded. More great music being added every week.\nThe design of the site is pretty, modern, leveraging lot of jQuery and flash magic. In the backend powered by the probably most powerful eCommerce platform - ATG eCommerce Suite.\nWe go back long time with ATG. Starting in 2001 when we (we means Montage at that time) decided to bid solution based on ATG for two major RFP's in federal government and won them both. During following years, we have digged deeper into very rich and powerful platform and built more functionality and added few more customers. This project was our first full eCommerce implementation based on ATG 2007.1. But definitely not the last one - it looks like despite the economy maladies, demand for eCommerce and specially ATG based eCommerce solution is surprisingly large and interesting amount of work is coming our way ...\nI am tremendously proud of what our team was able to deliver. It took lots of dedication and sweat: we had pretty aggressive deadline (full store was implemented in under two months) and complexities of the environment. To make me even more proud is that the system is running in production environment architected and developed by our team. It is not often that developers team has opportunity to be involved into complexities of the large enterprise system deployment and putting to production.\nAh, almost forgot - the URL is http://www.zik.ca/. See for yourself. Right now, only in French (primary target audience is French speaking Canadian population), English coming later.\nI would like to thank everybody who helped to make this an amazing project experience. We were lucky to build great relationship with both our customer and the end-customer, as well as with our development partners in Montreal working on different stores in Virtual Shopping Mall.\nThanks to ATG for such rich and powerful product suite. It is like great sports car: very powerful, requires skills to master it, but once you get it, you can do amazing things with it.\nAnd last but not least, big thanks to everybody from our delivery team that made this possible. You guys rock.\nBtw, if you would like to work with people that can build things like this, and have either ATG experience or at least solid J2EE, Spring, Hibernate and JSP/JSTL skills, send your resume to careers at thinknostic dot com.\nWe are hiring again :-).\nNo telecommuters please - you must be able to live and work either in Ottawa or Toronto. Speaking French is not required but is definitely a plus.\n","date":"February 18, 2009","externalUrl":null,"permalink":"/posts/2009-02-18-its-alive/","section":"Posts","summary":"I was aching to blog about this since December 18th, when our system quietly and gently slipped into public visibility. Marked as Beta (thanks, Google for making this a legitimate way how to go live) it comfortably made it through Christmas shopping season into 2009.\nNow when the site has been announced and mentioned few times in the media, I guess it's OK to mention it here too.\nWhat is \"it\" ? A new, fresh eCommerce site selling music. A lots of really good music. Without any DRM or any other nonsense, as plain good high quality (mostly 320 kps) MP3's. The selection is actually very good - starting from several hundred thousands in December to several few million songs when full catalog is loaded. More great music being added every week.\n","title":"It's alive !","type":"post"},{"content":"Here is the context: in order to upgrade iLife 08 to iLife'09 (which is very nice, btw), I had to install 10.5.6 upgrade. And according Murphy's law, one of the 2 GB DIMM's in my MacBook Pro went bad exactly during the OS-X upgrade process.\nIt had two rather unpleasant consequences:\nsome of the patch files got downloaded and saved in corrupted state The machine did not boot back after restart The second problem was fixed by replacing the bad DIMM, but the first caused that upgrade to 10.5.6 was impossible: the files were downloaded, verification failed, after restart I was back to square one. There was no obvious way how to \"undownload\" the files.\nThe Apple Support representative recommended downloading the update as DMG from Apple Downloads, and run installer. The DMG of 10.5.6 had over 300 MB, while the patch file was barely 190 MB, so I was wondering whether there is better way. As it turned out, it is very easy.\nThe location of the downloaded files is /Library/Updates which is normally almost empty:\nDuring update process, this is the location where OS-X will keep the downloaded files, as shown here:\nAll you need to do is to delete these downloads (keep the plist, of course) and try Software Updates again. The updater will re-download the files and everything will work as expected:\n","date":"February 7, 2009","externalUrl":null,"permalink":"/posts/2009-02-07-how-to-un-stuck-unsuccessful-os-x-upgrade/","section":"Posts","summary":"Here is the context: in order to upgrade iLife 08 to iLife'09 (which is very nice, btw), I had to install 10.5.6 upgrade. And according Murphy's law, one of the 2 GB DIMM's in my MacBook Pro went bad exactly during the OS-X upgrade process.\nIt had two rather unpleasant consequences:\nsome of the patch files got downloaded and saved in corrupted state The machine did not boot back after restart The second problem was fixed by replacing the bad DIMM, but the first caused that upgrade to 10.5.6 was impossible: the files were downloaded, verification failed, after restart I was back to square one. There was no obvious way how to \"undownload\" the files.\n","title":"How to un-stuck unsuccessful OS-X upgrade","type":"post"},{"content":"The centos 4.x we are using as platform for the VMWare VMs (yes, I know there is version 5, but we need to be compliant with RHEL 4.x because of the ATG requirements) installs by default the NTP client.\nHere is sequence of steps that needs to be performed to enable automatic synchronization of the clocks.\nmake sure the DNS works cat /etc/resolv.conf sudo vi /etc/resolv.conf and check that nameservers point to something meaningfull, e.g:\nnameserver 208.67.222.222 nameserver 208.67.220.220 nameserver 192.168.16.1 2) check that you have ntpd installed\ncat /etc/ntp.conf\n- inspect the content of the file, it is quite well documented\n3) make it work in runlevels 2345\n/sbin/chkconfig --list | grep ntpd\n- this will most likely show \"off\" for all runlevels\nsudo /sbin/chkconfig --level 2345 ntpd on\n4) Initial sync\nsudo /usr/sbin/ntpdate pool.ntp.org\n- do this twice, on second you should get very small difference\n5) Start service / restart service\nsudo /sbin/service ntpd start\nMaking this a blog post so that next time I need to do it I can easily find it :-). Maybe somebody else will find it useful as well.\n","date":"January 9, 2009","externalUrl":null,"permalink":"/posts/2009-01-09-vmware-and-slow-clocks-take-2/","section":"Posts","summary":"The centos 4.x we are using as platform for the VMWare VMs (yes, I know there is version 5, but we need to be compliant with RHEL 4.x because of the ATG requirements) installs by default the NTP client.\nHere is sequence of steps that needs to be performed to enable automatic synchronization of the clocks.\nmake sure the DNS works cat /etc/resolv.conf sudo vi /etc/resolv.conf and check that nameservers point to something meaningfull, e.g:\n","title":"VMWare and slow clocks - take 2","type":"post"},{"content":"I have noticed recently that most of our VMWare instances (and we are running decent fleet of them for the ATG Lab as well as internal system) if left without time synchronization, will loose get late quite a bit: some of them as much as hour or more a week.\nUnix date command unfortunately belongs to those commands that I am having troubles to remember and everytime I have to use it with parameters, I end up googling for examples ...\nThe following snippet is useful when correcting only time portion:\n[tkuser@jci-app ~]$ date Sat Jan 3 11:28:12 EST 2009 [tkuser@jci-app ~]$ sudo date -s \u0026#34;13:45\u0026#34; Password: Sat Jan 3 13:45:00 EST 2009 [tkuser@jci-app ~]$ date Sat Jan 3 13:45:04 EST 2009 ","date":"January 4, 2009","externalUrl":null,"permalink":"/posts/2009-01-04-vmware-and-slow-clocks/","section":"Posts","summary":"I have noticed recently that most of our VMWare instances (and we are running decent fleet of them for the ATG Lab as well as internal system) if left without time synchronization, will loose get late quite a bit: some of them as much as hour or more a week.\nUnix date command unfortunately belongs to those commands that I am having troubles to remember and everytime I have to use it with parameters, I end up googling for examples ...\n","title":"VMWare and slow clocks","type":"post"},{"content":"","date":"January 2, 2009","externalUrl":null,"permalink":"/tags/iphone/","section":"Tags","summary":"","title":"IPhone","type":"tags"},{"content":"Just tried out to switch the iPhone to automatic Date and Time setting with 3G on. The time jumped from 11:31 to 11:30 (my iPhone was about 1 minute too fast) and STAYED THERE.\nThis could mean that the issue is finally fixed. Can anybody confirm that ?\n","date":"January 2, 2009","externalUrl":null,"permalink":"/posts/2009-01-02-weird-rogers-3g-network-error-fixed/","section":"Posts","summary":"Just tried out to switch the iPhone to automatic Date and Time setting with 3G on. The time jumped from 11:31 to 11:30 (my iPhone was about 1 minute too fast) and STAYED THERE.\nThis could mean that the issue is finally fixed. Can anybody confirm that ?\n","title":"Weird Rogers 3G network error - fixed ?","type":"post"},{"content":"Two screencasts, about 80 and 40 minutes long are available at:\nhttp://excess.org/article/2008/07/ogre-git-tutorial/\nCourtesy by fellow Ottawan Bert Trojanowski. Really nice job of providing deep enough technical understanding with good illustrative examples.\nIf you want to get into distributed version control (which is IMHO way to go), check this out.\n","date":"January 2, 2009","externalUrl":null,"permalink":"/posts/2009-01-02-excellent-free-git-tutorial/","section":"Posts","summary":"Two screencasts, about 80 and 40 minutes long are available at:\nhttp://excess.org/article/2008/07/ogre-git-tutorial/\nCourtesy by fellow Ottawan Bert Trojanowski. Really nice job of providing deep enough technical understanding with good illustrative examples.\nIf you want to get into distributed version control (which is IMHO way to go), check this out.\n","title":"Excellent free Git tutorial","type":"post"},{"content":"Since about Sunday, Dec 7th (I remember exactly because I noticed it when leaving the regular ByMUG meeting at Patty Bolands) my iPhone for no particular reason decided to translocate itself to GMT+1 time zone. It was not visible immediately, only emails received at 16:20 were shown as received 6 hour in the future.\nAll this without any changes or installing anything on my end ...\nThe Clock application showed what was wrong (this snapshot was taken on Sunday, 16:02 Ottawa time):\nI tried to change settings for Date and Time to manual and correct the problem, but any time I switched back to keeping time synchronized automatically it jumped back to wrong time.\nI believe this is a Rogers problem as it happens only when 3G is on. With Edge, you can safely switch forth and back beween any impact on the correct time. It would look like the iPhone is getting wrong information from the 3G network about time or about timezone (despite the settings of timezone to Ottawa, Canada). I tried Toronto and Montreal for timezone settings - same results.\nCurrently there are two workarounds:\n1) Use Edge and suffer the slow speed, partially compensated by better battery life\n2) Use manual setting and take into account that without network synchronization time your phone can get out of sync byt as much as few minutes\nper day.\nThere is also discussion thread on Apple site.\nI suggest that everybody that experiences this calls Rogers and requests fix. I would also consider asking for refund of part of the data plan, because this problem basically does not allow to use the 3G service we are paying for.\nChances are slim for getting few bucks back but maybe it will help to elevate the severity of the problem in their Bugzilla (or whatever they use for issue tracking).\n","date":"December 16, 2008","externalUrl":null,"permalink":"/posts/2008-12-16-weird-rogers-3g-network-error/","section":"Posts","summary":"Since about Sunday, Dec 7th (I remember exactly because I noticed it when leaving the regular ByMUG meeting at Patty Bolands) my iPhone for no particular reason decided to translocate itself to GMT+1 time zone. It was not visible immediately, only emails received at 16:20 were shown as received 6 hour in the future.\nAll this without any changes or installing anything on my end ...\nThe Clock application showed what was wrong (this snapshot was taken on Sunday, 16:02 Ottawa time):\n","title":"Weird Rogers 3G network error","type":"post"},{"content":"I have noticed few of this beauties in Kanata Chapters. Nice replacement for the beaten up CRT terminals that used to be around. They somehow looked right and familiar from the distance.\nBeautiful screen, with touch capability.\nNice presentation and user interface.\nThe keyboard with unique personality.\nAnd after looking closer, it was very obvious why:\nProper keyboard simply must have Command key ;-)\nPS:I am sorry for bad quality of pictures - iPhone camera under bad light conditions...\n","date":"December 1, 2008","externalUrl":null,"permalink":"/posts/2008-12-01-chapters-goes-mac/","section":"Posts","summary":"I have noticed few of this beauties in Kanata Chapters. Nice replacement for the beaten up CRT terminals that used to be around. They somehow looked right and familiar from the distance.\nBeautiful screen, with touch capability.\nNice presentation and user interface.\nThe keyboard with unique personality.\nAnd after looking closer, it was very obvious why:\nProper keyboard simply must have Command key ;-)\n","title":"Chapters goes Mac","type":"post"},{"content":"I started to have this error about week ago, out of the blue. I was not aware of making any changes, but suddenly could not reply to an email, send new email or even forward existing email in the iPhone default Mail application. I am using GMail account and because other clients on different platforms worked OK, I suspected either Rogers or Apple. I was trying several possible fixes (and used Safari and Gmail web access - which is not much fun).\nHere is what did NOT resolve the problem:\ndeleting and recreating the account upgrading to firmware 2.2 resetting and restoring the phone Finally, the fix was to switch off all Gmail SMTP servers (for no particular reason there were two) and switch on the Rogers SMTP. To do that, go to Settings, Mail Contacts Calendar, click on account, select SMTP server.\nI do not remember entering any of these servers, so they must have been created automagically when creating the GMail account in the Mail app. The Rogers account that works is all greyed out, the username and password is set to optional and the part of URL showing is smtp.rogerswirelessdata.c...\nBecause I have disabled BOTH Gmail server, the Default settings now shows under SMTP 'No Server' - but it works :-)\n","date":"November 24, 2008","externalUrl":null,"permalink":"/posts/2008-11-24-fix-for-sender-address-is-invalid-error-on-iphone-3g/","section":"Posts","summary":"I started to have this error about week ago, out of the blue. I was not aware of making any changes, but suddenly could not reply to an email, send new email or even forward existing email in the iPhone default Mail application. I am using GMail account and because other clients on different platforms worked OK, I suspected either Rogers or Apple. I was trying several possible fixes (and used Safari and Gmail web access - which is not much fun).\n","title":"Fix for 'Sender address is invalid' error on iPhone 3G","type":"post"},{"content":"If you want to watch YouTube video on the plane (and Google TechChannel has some amazing collection of videos), here is how to save it to disk, without any tools or third party program, using just your Mac and Safari out of the box.\nGo to YouTube page and select video you are interested in in Safari. While playing, press Option-Command-A which opens Activity window. Locate the video stream - it will be the largest item in the list. Double click it, which causes Safari to download it.\nAfter finish, go to download folder, locate the file (usually named get_video) and rename it to SOMETHING.flv. Open with any FLV enabled player - VLC works like charm.\nAt the end usual disclaimer: you should always make sure you do not violate copyright law or law of the country you reside in. I am not recommending or endorsing any behaviour that would cause violation of copyright law, merely describing interesting technical feature of a popular browser ;-).\n","date":"November 20, 2008","externalUrl":null,"permalink":"/posts/2008-11-20-how-to-save-local-copy-of-youtube-video/","section":"Posts","summary":"If you want to watch YouTube video on the plane (and Google TechChannel has some amazing collection of videos), here is how to save it to disk, without any tools or third party program, using just your Mac and Safari out of the box.\nGo to YouTube page and select video you are interested in in Safari. While playing, press Option-Command-A which opens Activity window. Locate the video stream - it will be the largest item in the list. Double click it, which causes Safari to download it.\n","title":"How to save local copy of YouTube video","type":"post"},{"content":"Since few weeks we have started internally use an interesting microblogging tool named Yammer. It works very similarly to Twitter, which means that you are posting very short posts, focusing on the stuff you are doing or working on. Unlike with Twitter, Yammer is company oriented and your posts will be visible ONLY to the recipients that share your company's email address.\nYammer is free service with interesting business model: everybody can join your company's network (if that person has proper email address), but to gain administrative rights, you have to pay dollar a month per user. I actually like this approach because it gives hope that the service will be around and available next year :-)\nYammer offers browser version (very nicely done, btw), desktop client for both Mac and Windows and (finally) very usable iPhone application. This means that you can follow and communicate with your colleagues even while sitting in the bus or train. You can also post by email and receive posts via email, if you choose so - either as individual emails or as daily summary.\nLatest update added option to create groups for really focused communication and managing the channel noise.\nSo far the uptake and experience within the company was very positive. What I really like is that it allows good alternative and communication middle road between instant messaging (which is too interactive and thus too distracting) and emails (which is too little interactive). It helps create better information flow and keep in touch with people that are out on client's location - which is very important for a professional services organizations like us. It is also extremly important for distributed teams, and because my crystal ball foretells strong likelihood of geographical expansion in very near future, it may become even more useful.\nToo bad this service (or Twitter for that matter) did not exist back in 2003 - I could have used it a lot while working in distributed development team spanning 6 timezones.\nRecommended.\n","date":"November 18, 2008","externalUrl":null,"permalink":"/posts/2008-11-18-sane-version-of-twitter/","section":"Posts","summary":"Since few weeks we have started internally use an interesting microblogging tool named Yammer. It works very similarly to Twitter, which means that you are posting very short posts, focusing on the stuff you are doing or working on. Unlike with Twitter, Yammer is company oriented and your posts will be visible ONLY to the recipients that share your company's email address.\nYammer is free service with interesting business model: everybody can join your company's network (if that person has proper email address), but to gain administrative rights, you have to pay dollar a month per user. I actually like this approach because it gives hope that the service will be around and available next year :-)\n","title":"Sane version of Twitter","type":"post"},{"content":"Several people asked what is going on with me: no blog posts for almost a month, litlle presence on Gtalk / MSN. It is simpler to answer this way that write same email over and over.\nUnfortunately the reason for being quiet is not that I am taking time off and enjoying myself somewhere in Caribbean on a secluded island without internet connection. Those who know me well also know that I would never go somewhere without access to Web for longer period of time than week - and even that would cause serious withdrawal issues. I am in Ottawa or Montreal or somewhere in between - physically or virtually.\nAlso - I am OK and am doing great as well. Main reason why the blog was quite neglected for last 6 weeks is actually rather lame: work.\nWe have landed pretty large project with quite ambitious deadline. It is very exciting opportunity in eCommerce space, based on latest and greatest ATG Commerce 2007.1. This project was great opportunity to explore new features and update my ATG skills. If you know the framework, enough said. If you do not know ATG, it is in eCommerce space something like Ferrari or Lamborghini in cars - very powerful with many unique features, rather exclusive and consequently quite expensive. Enterprise Java in its very serious incarnation :-). I have spent lot of time on this project and have gained a lot of interesting insight not only in areas related to coding, but also in deployment, release management, clustering and so on. It absorbed me so completely that I stopped blogging, limited Web surfing, put my Ruby/Cocoa experiments on hold. I am way behind in my podcast listening (all in total, accumulated over 15 episodes only in TWIT network podcasts itself).\nSo what has changed that I am back ? Did the project end ?\nNope, quite the oposite, we are hitting QA phase which will be followed by Phase 2 enhancements and busiest time is still ahead of us, as we will be live and selling for this Christmas season. And also few more projects are on the horizon.\nI simply realized that with the strong upward trend of our business (we had record month in October, November looks also very strong) and very exciting things in our immediate corporate future, I cannot simply put life outside of work and my other \"pet projects\" on pause and hope I woud get back to it later. Because there will always be much bigger demand on time and deadlines and challenges and delaying can very well be cancelling them.\nRather than postponing the \"rest of it\", I am actively searching for better ways how to intertwine these two worlds. I will keep you posted about the progress :-)\n","date":"November 16, 2008","externalUrl":null,"permalink":"/posts/2008-11-16-about-time-to-break-the-silence/","section":"Posts","summary":"Several people asked what is going on with me: no blog posts for almost a month, litlle presence on Gtalk / MSN. It is simpler to answer this way that write same email over and over.\nUnfortunately the reason for being quiet is not that I am taking time off and enjoying myself somewhere in Caribbean on a secluded island without internet connection. Those who know me well also know that I would never go somewhere without access to Web for longer period of time than week - and even that would cause serious withdrawal issues. I am in Ottawa or Montreal or somewhere in between - physically or virtually.\n","title":"About time to break the silence","type":"post"},{"content":"This was error I have received while trying to convert physical machine running Windows 2003 SP1 into VMWare image.\nAfter some googling around and experimenting (this link was most helpful to point me in correct direction) I found solution that worked for me.\nAll I had to do was to disable Floppy Drive in the System applet of Control panel. After this, the conversion continued and right now is squeezing 100 GB disk into 50 2 GB files on external USB disk.\n","date":"October 19, 2008","externalUrl":null,"permalink":"/posts/2008-10-19-vmware-converter-error-p2verror-unable_to_determine_guest_os/","section":"Posts","summary":"This was error I have received while trying to convert physical machine running Windows 2003 SP1 into VMWare image.\nAfter some googling around and experimenting (this link was most helpful to point me in correct direction) I found solution that worked for me.\nAll I had to do was to disable Floppy Drive in the System applet of Control panel. After this, the conversion continued and right now is squeezing 100 GB disk into 50 2 GB files on external USB disk.\n","title":"VMWare Converter error P2VError UNABLE_TO_DETERMINE_GUEST_OS","type":"post"},{"content":"Yes, I mean *that* dry, boring Deweys Decimal Classification used by libraries around the world.\nHere is what I noticed in Ottawa Public Library:\nCan you imagine two subjects so far apart from each other - and sometimes sooo close ;-)\n","date":"October 13, 2008","externalUrl":null,"permalink":"/posts/2008-10-13-deweys-classification-can-be-funny/","section":"Posts","summary":"Yes, I mean *that* dry, boring Deweys Decimal Classification used by libraries around the world.\nHere is what I noticed in Ottawa Public Library:\nCan you imagine two subjects so far apart from each other - and sometimes sooo close ;-)\n","title":"Dewey's Classification can be funny","type":"post"},{"content":"A wonderful gem I found here:\nI remember telling a friend\nthat being a project manager\nis a little like being a bouncer:\nwhere there's a problem *here*\nand a door *there*\nand it's your job to get the problem out the door.\nSo\nFor some a gentle gesture will do\nwhile others need a push\nand still others need to be picked up by their pants and carried\nBut!\nIn no case should you ever let someone get *further* from the door.\nSo that's me.\nBy Merlin Mann :-)\nI dedicate this to all my friends and colleagues who face daily the Project Management challenges, specially to Peter, Julia, Mike and Milos.\n","date":"September 30, 2008","externalUrl":null,"permalink":"/posts/2008-09-30-project-management-in-a-nutshell/","section":"Posts","summary":"A wonderful gem I found here:\nI remember telling a friend\nthat being a project manager\nis a little like being a bouncer:\nwhere there's a problem *here*\nand a door *there*\nand it's your job to get the problem out the door.\nSo\nFor some a gentle gesture will do\nwhile others need a push\nand still others need to be picked up by their pants and carried\n","title":"Project Management - in a Nutshell","type":"post"},{"content":"It is always a nice surprise to find something that is free and actually useful on the Net :-). Like this one: a fellow Ottawan Karl Sequin wrote and generously made available as free download \"Foundations of programming\" eBook.\nHe touches many topics of various levels from high level design concepts (dependency injection) to low level \"Back to Basics\" - how memory allocation and pointers work. Especially the later is often neglected and overlooked (and consequently misunderstood) by younger developers who started their education with a garbage collected language such as Java or C# and never were exposed to beauty and horrors of C ;-)\nThe book is using .NET and C# as platform, but the applicability of the chapters goes way beyond the Windows or Microsoft world. After all, Alt.Net has very close relations with Java world.\nIf you have time, give it a look. Were it not free, I would say it is worth every penny. Now I can only say it is definitely worth the time you spend on it.\nThanks Karl, I hope I'll meet you in person sometimes. The advantage of living in Ottawa is that you have lots of smart people around you :-).\n","date":"September 27, 2008","externalUrl":null,"permalink":"/posts/2008-09-27-free-ebook-on-altnet/","section":"Posts","summary":"It is always a nice surprise to find something that is free and actually useful on the Net :-). Like this one: a fellow Ottawan Karl Sequin wrote and generously made available as free download \"Foundations of programming\" eBook.\nHe touches many topics of various levels from high level design concepts (dependency injection) to low level \"Back to Basics\" - how memory allocation and pointers work. Especially the later is often neglected and overlooked (and consequently misunderstood) by younger developers who started their education with a garbage collected language such as Java or C# and never were exposed to beauty and horrors of C ;-)\n","title":"Free eBook on ALT.NET","type":"post"},{"content":"Few days ago, I have received an email asking to attend the SpringSource conference and offering $300 discount if I decide to buy before end of month. The timining was pretty ironical, considering the recent contraversy about SpringSource Entreprise Maintenance policy change. The was a heated discussion on TheServerside.com and even FAQ was compiled by Rod Johnson to explain the whole thing.\nSo what is the issue: SpringSource, commercial entity behind community driven Spring Framework decided to capitalize on the investment and push the community toward paid service suport contract. Whether or not it was related to funding round and VC's entering the game, is not important. Unfortunately, the terms were not really well explained and SpringSource did initially very poor job explaining and communicating the actual change. The community overreacted and lot of people started to call for code fork, project Summer or similar - or switching to different framework.\nWhat the change really means is that maintenance releases will not be available (as binary, official downloads) after 3 months, unless you pay for the support. It means that using new policy after let's say release 2.0, only for three months everybody could download binary distributions of 2.0.1, 2.0.3 etc. If at the end of month 3 you would need fixes in the 2.0 branch, you would be on your own. The source code repository with 2.0 branch would still be available, with fixes committed (see later) but without tags (or labels) and certainly without pre-packaged download of 2.0.4, 2.0.5. You could compile the actual head of the 2.0 branch yourself, but it would not be clear what version you actually run.\nThis is actually not such terrible limitation as it may seem. Maintaining old code base and backporting the changes from trunk into fixes in branches is lot of work, requires testing and so on. SpringSource did invest a lot into the codebase and as commercial entity provides service to the users. The release management and software maintenance is slightly different type of work that developing new great release, and I can imagine that there are even less contributors and volunteers for this (seldom appreciated) kind of work. Multiply that with many branches and you'll see the magnitude of the problem.\nWhat did SpringSource do wrong, in my opinion is that they are taking away something that was available for the community for free and that created lot of negative sentiment. There are two ways how to push people to pay for free service - and cutting unless you pay is wrong one. Right way is to offer more on top of what is available for free, something that has value specifically for enterprise clients. There are several areas where there is a need: more and much better samples, template applications, guides, tutorials. Their availability has huge value for customers in saving development time and better quality of the products using the Spring platform.\nThere are several technical subtleties that are in open: the FAQ says that the changes and fixes from trunk will be available in the maintenance branches, but does not say when. Delaying changes can be powerful argument ... Lack of tags in public repository also implies existence of private repository with these tags - how else could the SpringSource build the \"supported releases\". The existence of two repositories in project (unless you use distributed VCS, of course) is often starting point of splitting project to payware and limited \"community edition\". I hope this will not happen to Spring.\nThe most unfortunate impact of the maintenance policy decision may be for the Spring based opensource projects, that helped a lot to establish acceptance of the platforms over last few years. Dilema of facing either cascading changes of permanent upgrades just to keep in sync with latest trunk version, or permanently monitoring the branch to see which of the changes are important - in absence of \"official\" maintenance release with defined bug fixes etc can be an issue for many projects. I hope SpringSource will find workarounds and solutions for these.\nDespite of that, forking Spring would be very bad idea. The very last thing enterprise Java needs is another framework that is esentially same or very similar than existing one. SpringSource employs brilliant engineers, Spring community also has great contributors - what is the point of splitting the forces when there is no architectural disagreement, the issue is \"just money\" ?\nForking also does not solve the core problem: who will be providing the community service of maintaining and building the old releases. The maintainers of Summer codebase (or whatever the name of Spring forked successor would be) will face the same dilema - choose between working for free forever or finding way how to employ enough manpower to keep the balls rolling.\nI would recommend that instead of forking Spring codebase, whoever feels like it, try instead to fill in the gap and provide the \"inofficial official\" builds, a \"community maintenance releases\" as counterpart and alternative to official SpringSource maintenance releases for enterprise (== paying) customers. This would actually help the project and all projects that depend on it much more than asking them to switch.\nIt would also not hurt SpringSource - I am convinced that they would loose very little revenue (if any) because of that. It has been done (Centos vs RHEL). If my project would be based on Spring platform and not on commercial Java server (which it is not) and the support cost would be reasonable (which it IMHO is), I would happily pay for priviledge to have access to the people of Juergen Holler's caliber (and many others).\nLet's face it, folks: when it comes to support and software maintenance and similar less attractive areas of our profession, there is definitely no such thing as free lunch ...\n","date":"September 25, 2008","externalUrl":null,"permalink":"/posts/2008-09-25-after-the-spring-storm/","section":"Posts","summary":"Few days ago, I have received an email asking to attend the SpringSource conference and offering $300 discount if I decide to buy before end of month. The timining was pretty ironical, considering the recent contraversy about SpringSource Entreprise Maintenance policy change. The was a heated discussion on TheServerside.com and even FAQ was compiled by Rod Johnson to explain the whole thing.\nSo what is the issue: SpringSource, commercial entity behind community driven Spring Framework decided to capitalize on the investment and push the community toward paid service suport contract. Whether or not it was related to funding round and VC's entering the game, is not important. Unfortunately, the terms were not really well explained and SpringSource did initially very poor job explaining and communicating the actual change. The community overreacted and lot of people started to call for code fork, project Summer or similar - or switching to different framework.\n","title":"After the Spring Storm","type":"post"},{"content":"Before I forget :-)\n1) The Git Magic\n2) Two git books Pragmatic Git Book and Git internals - nice complement each other\n3) Linus Torvalds slightly offensive and very funny talk at Google\nin addition to great, precise but not necessarily most digestable manual ...\n","date":"September 20, 2008","externalUrl":null,"permalink":"/posts/2008-09-20-three-great-git-resources/","section":"Posts","summary":"Before I forget :-)\n1) The Git Magic\n2) Two git books Pragmatic Git Book and Git internals - nice complement each other\n3) Linus Torvalds slightly offensive and very funny talk at Google\nin addition to great, precise but not necessarily most digestable manual ...\n","title":"Three great Git resources","type":"post"},{"content":"I was brave and updated right away last Friday, as soon as the update appeared, both the iTunes and the iPhone firmware. And so far, so good. Initial observations are quite positive - at least so far, from using it during last few days.\nI never had any issues with the dropped calls, so I cannot report any improvement. What seems to work better is browsing: I get much less (if any) connection errors. It is hard to say whether it was the firmware, or Rogers fixed something - or the fixed firmware causes less issues to network - it looks like improvement.\nWhat is definitely a huge improvement is sync time. Backup now does not take 5 minutes+, it is down (after initial one) to less than minute and whole sync with transfering new podcasts and application updates is done in 2-3 minutes max. The application update still takes about same amount time - at least it feels like it.\nOverall, there are few nice little improvements, like this one in list of podcasts:\nNote the detail info that indicates half-finished podcasts and shows how much of the audio is left:\nNice touch (pun intended) ;-)\n","date":"September 16, 2008","externalUrl":null,"permalink":"/posts/2008-09-16-iphone-firmware-21-first-impressions/","section":"Posts","summary":"I was brave and updated right away last Friday, as soon as the update appeared, both the iTunes and the iPhone firmware. And so far, so good. Initial observations are quite positive - at least so far, from using it during last few days.\nI never had any issues with the dropped calls, so I cannot report any improvement. What seems to work better is browsing: I get much less (if any) connection errors. It is hard to say whether it was the firmware, or Rogers fixed something - or the fixed firmware causes less issues to network - it looks like improvement.\n","title":"iPhone firmware 2.1 - first impressions","type":"post"},{"content":"If this thing is real, I am buying one. Regardless that I really, really do not need another Mac :-). Form factor of thin screen of size 9-12 inch, with reasonable subset of touch gestures would be EXACTLY what I need from a internet terminal / reader. Plus the option to tether it with iPhone for ubiquitous connectivity ...\n","date":"September 11, 2008","externalUrl":null,"permalink":"/posts/2008-09-11-too-good-to-be-true-2/","section":"Posts","summary":"If this thing is real, I am buying one. Regardless that I really, really do not need another Mac :-). Form factor of thin screen of size 9-12 inch, with reasonable subset of touch gestures would be EXACTLY what I need from a internet terminal / reader. Plus the option to tether it with iPhone for ubiquitous connectivity ...\n","title":"Too good to be true ?","type":"post"},{"content":"Here is my situation: I am using three different Macs (Macbook Pro and two iMacs - one at home and occasionally second one at work) and need to keep the contacts and calendars synchronized at least between two of them (MBP and home iMac). I use iPhone which also has calendar and contacts. And in the cloud, there is Google calendar. Actually, more than one: my own calendar and company shared calendar of my colleagues from Thinknostic. Quite a challenge to keep it all in sync.\nHere is the setup that works for me:\nTo synchronize iCals between different Macs as well as between Mac and iPhone, the most seamless and completely painless way seems to be using Mobile Me. I registered for Mobile Me back when it started - just to grab the name (miro at me dot com), and have not used it much at first. Thanks the 30+60 day extension, I have still until mid November ti decide whether I will keep it or no. The sync feature alone seems to be worth at least half of the subscription price. The other half is push email and really easy way how to synchronize files between Macs ... Also to have online access to your contacts when you are not on a Mac can be useful sometimes. But back to the workflow:\nTheoretically, both iCal and address book gets synchronized every time you sync the iPhone with Mac. This is not really as useful as it may sound, because I do the sync about once a week to download images from camera and upload new podcasts. And to update the apps, of course. I would not do that more often, for simple reason: the synchronization takes forever. Ten minutes at least. With Mobile me, you can sync as often as you want (every minute if you really want) - and also access the information online via browser.\nTo synchronize Google calendar used to require some helper applications, like GCalDaemon (free, opensource) or Spanning Sync. Not any more. Since Google opened up the API this summer, it can be done out of the box: read more on here\nThis solution is almost perfect, the only relatively minor problem is that sync between iCal and Google does not include iPhone: the calendars that you have added to iCal and are coming from GCal are left out - Mobile Me synchronization does not include calendars not created or owned by iCal application. This is not such a big deal as it may seem because from iPhone, you can always access the Google calendar by using the very good mobile Web UI.\n","date":"September 9, 2008","externalUrl":null,"permalink":"/posts/2008-09-09-calendar-synchronization-between-iphone-google-calendars-and-ical/","section":"Posts","summary":"Here is my situation: I am using three different Macs (Macbook Pro and two iMacs - one at home and occasionally second one at work) and need to keep the contacts and calendars synchronized at least between two of them (MBP and home iMac). I use iPhone which also has calendar and contacts. And in the cloud, there is Google calendar. Actually, more than one: my own calendar and company shared calendar of my colleagues from Thinknostic. Quite a challenge to keep it all in sync.\n","title":"Calendar synchronization between iPhone, Google calendars and iCal","type":"post"},{"content":"The 97 things that every software architect should know:\nhttp://97-things.near-time.net/wiki\nActually, it's 87 but new are still coming. You may add your piece if it is not yet there ...\nMilos - thanks for the link.\n","date":"September 8, 2008","externalUrl":null,"permalink":"/posts/2008-09-08-good-read-not-only-for-software-architects/","section":"Posts","summary":"The 97 things that every software architect should know:\nhttp://97-things.near-time.net/wiki\nActually, it's 87 but new are still coming. You may add your piece if it is not yet there ...\nMilos - thanks for the link.\n","title":"Good read - not only for software architects","type":"post"},{"content":"Here is a snapshot I took during today's trip to Chapters @ Rideau. While walking out, the placement of some books caught my eye:\nNote the \"headlines\" in the background of the Vista books: \"Ailments and diseases\". Certainly unintended and a bit childish, but I found it hilariously funny :-)\n","date":"September 7, 2008","externalUrl":null,"permalink":"/posts/2008-09-07-proper-shellspace-above-all/","section":"Posts","summary":"Here is a snapshot I took during today's trip to Chapters @ Rideau. While walking out, the placement of some books caught my eye:\nNote the \"headlines\" in the background of the Vista books: \"Ailments and diseases\". Certainly unintended and a bit childish, but I found it hilariously funny :-)\n","title":"Proper shellspace above all :-)","type":"post"},{"content":"Everybody seems to be crazy about Chrome, the new superfast Google browser. The odes on speed sounded quite exaggerated, so I had to try it. I opened up again my old battered Fujitsu Lifebook and after 3 reboots (it was not used for about 2 months and Windows update had to have its patching done) I downloaded and installed it.\nThe rumors were not unsubstantiated ... it IS considerably speedier than anything else, including Opera. I have not seen any issues on the few sites I have tried - everything seems to work just fine.\nSo why back to Firefox ?\nThree reasons. First, Chrome does not exist for Mac or Linux and I am not going to use Windows in VM just to surf web, that would be kinda silly. This will be presumably fixed soon - according to the blog.\nSecond, the Firefox extensions are simply too good to be missed. I happily exchange speed for goodness of Firebug.\nAnd third: the IS a catch and many people noticed it. The Google's EULA says:\n11. Content license from you\n11.1 You retain copyright and any other rights you already hold in Content which you submit, post or display on or through, the Services. By submitting, posting or displaying the content you give Google a perpetual, irrevocable, worldwide, royalty-free, and non-exclusive license to reproduce, adapt, modify, translate, publish, publicly perform, publicly display and distribute any Content which you submit, post or display on or through, the Services. This license is for the sole purpose of enabling Google to display, distribute and promote the Services and may be revoked for certain Services as defined in the Additional Terms of those Services.\n11.2 You agree that this license includes a right for Google to make such Content available to other companies, organizations or individuals with whom Google has relationships for the provision of syndicated services, and to use such Content in connection with the provision of those services.\n11.3 You understand that Google, in performing the required technical steps to provide the Services to our users, may (a) transmit or distribute your Content over various public networks and in various media; and (b) make such changes to your Content as are necessary to conform and adapt that Content to the technical requirements of connecting networks, devices, services or media. You agree that this license shall permit Google to take these actions.\n11.4 You confirm and warrant to Google that you have all the rights, power and authority necessary to grant the above license.\nI am not a lawyer, but this seems to be little bit too much. Google already has all my emails and knows most about my searches :-( ... but I have no intention transfer to them e.g. ownership of my photos that could upload to Smugmug using their browser. Or similar.\nFortunately most of the components are opensource, and I am certain that the good pieces will make their way to our computers packaged in some alternative open and user friendly speed devil browser. Ideally under Apache or BSD license ;-)\nUntil that time - by bye Chrome. Uninstalled. And I am not alone that did so ...\n","date":"September 4, 2008","externalUrl":null,"permalink":"/posts/2008-09-04-chrome-is-interesting-but-ill-stick-with-firefox/","section":"Posts","summary":"Everybody seems to be crazy about Chrome, the new superfast Google browser. The odes on speed sounded quite exaggerated, so I had to try it. I opened up again my old battered Fujitsu Lifebook and after 3 reboots (it was not used for about 2 months and Windows update had to have its patching done) I downloaded and installed it.\nThe rumors were not unsubstantiated ... it IS considerably speedier than anything else, including Opera. I have not seen any issues on the few sites I have tried - everything seems to work just fine.\n","title":"Chrome is interesting, but I'll stick with Firefox ...","type":"post"},{"content":"One feature that I strongly miss from Objective C are namespaces. Inability to avoid name clash between your classes sometimes really stands in your way.\nI am reading S. Kochan's book \"Programming in Objective C\" and in one of the examples he creates the class Point. Unfortunately, there already is struct Point defined in mactypes.h.\nThe solution is easy - rename the darn Point to something like TKPoint ... at least that is what Cocoa naming guide recommends. It is probably matter of getting used to it - but I still find the solution suggested by Kevin Hoffman much more elegant - too bad it is only theoretical. Much nicer than NSHack ;-)\n","date":"September 2, 2008","externalUrl":null,"permalink":"/posts/2008-09-02-objective-c-i-really-miss-namespaces/","section":"Posts","summary":"One feature that I strongly miss from Objective C are namespaces. Inability to avoid name clash between your classes sometimes really stands in your way.\nI am reading S. Kochan's book \"Programming in Objective C\" and in one of the examples he creates the class Point. Unfortunately, there already is struct Point defined in mactypes.h.\nThe solution is easy - rename the darn Point to something like TKPoint ... at least that is what Cocoa naming guide recommends. It is probably matter of getting used to it - but I still find the solution suggested by Kevin Hoffman much more elegant - too bad it is only theoretical. Much nicer than NSHack ;-)\n","title":"Objective C: I really miss namespaces","type":"post"},{"content":"","date":"September 2, 2008","externalUrl":null,"permalink":"/tags/objectivec/","section":"Tags","summary":"","title":"Objectivec","type":"tags"},{"content":"I have started to seriously play with Objective C and XCode about week ago. So far it was very pleasant experience. I really like the language - feels like Ruby (or Smalltalk if you want) with rocket launcher: very powerful, blastingly fast and dangerous like hell. No array boundary checks as in Java :-).\nThe XCode was not bad experience either. Here my very long Eclipse and Visual Studio history is going a bit in the way, as the things often works quite different. Not necessarily worse, but different. It would be too early to judge it - not before I get more proficient in both Objective-C and XCode and learn more Cocoa goodness.\nTwo things however are so annoying, that I have to mention them right now:\n1) Setting breakpoints was gamble - sometimes it worked, sometimes it did not. I could not figure out why, until I found here that you must in Preferences -\u0026gt; Debug switch off the 'Lazy loading symbols'. After re-entering the breakpoints, I finally got it to behave as expected.\n2) Trying to add existing files to a projects crashes the XCode with the following:\nThe console window shows error:\nPM Xcode[34563] *** Terminating app due to uncaught exception \u0026#39;NSInvalidArgumentException\u0026#39;, reason: \u0026#39; *** -[NSAutoreleasePool stopObservingModelObject:]: unrecognized selector sent to instance 0x32da240\u0026#39; which is clearly a bug. I tried to reboot (it was about time after running for over two weeks anyway), no help.\nWeird is that I remember doing that before without any problems ... Workaround is use drag and drop, of course, but I wish Apple would fix this Really Soon, as it is plainly embarrassing ...\nI have seen crashes like this in Visual Studio, but Eclipse was rock solid environment despite the very complex plugins ecosystem, so it is hard to go back to use something blowing under your hands ...\n","date":"September 1, 2008","externalUrl":null,"permalink":"/posts/2008-09-01-xcode-annoyances/","section":"Posts","summary":"I have started to seriously play with Objective C and XCode about week ago. So far it was very pleasant experience. I really like the language - feels like Ruby (or Smalltalk if you want) with rocket launcher: very powerful, blastingly fast and dangerous like hell. No array boundary checks as in Java :-).\nThe XCode was not bad experience either. Here my very long Eclipse and Visual Studio history is going a bit in the way, as the things often works quite different. Not necessarily worse, but different. It would be too early to judge it - not before I get more proficient in both Objective-C and XCode and learn more Cocoa goodness.\n","title":"XCode annoyances","type":"post"},{"content":"A friend made me aware of this (thanks, Peter):\nThe Inside Deets on iPhone 2.0.2 and Dropped Calls\nhttp://www.roughlydrafted.com/2008/08/28/the-inside-deets-on-iphone-202-and-dropped-calls/\nSounds like plausible explanation.\nIt is not the network that is fault but the interaction of the bad\npower control algorithm in 2.0 and 2.0.1 software and the network that\nis at fault. The sooner everybody is running 2.0.2 software the better\nthings will be. Having seen the graphs the 2.0.2 software has already\nstarted to make difference.\n","date":"August 28, 2008","externalUrl":null,"permalink":"/posts/2008-08-28-more-on-kcferrordomaincfnetwork-error-302/","section":"Posts","summary":"A friend made me aware of this (thanks, Peter):\nThe Inside Deets on iPhone 2.0.2 and Dropped Calls\nhttp://www.roughlydrafted.com/2008/08/28/the-inside-deets-on-iphone-202-and-dropped-calls/\nSounds like plausible explanation.\nIt is not the network that is fault but the interaction of the bad\npower control algorithm in 2.0 and 2.0.1 software and the network that\nis at fault. The sooner everybody is running 2.0.2 software the better\nthings will be. Having seen the graphs the 2.0.2 software has already\nstarted to make difference.\n","title":"More on kCFErrorDomainCFNetwork Error 302","type":"post"},{"content":"After everything-but-quiet summer, things got even busier and we need to add more great people to our teams.\nAt the moment we're looking for\n* Junior Java developers\n* Intermediate Java developers\n* Intermediate .Net developers\n* Senior .Net developers\n* Junior Graphics/UI/Multimedia Designer\nSorry - no teleworking, you must be local to apply. If you feel like fitting in - or know somebody in Ottawa that would fit, email Miro at thinknostic dot com ...\n","date":"August 26, 2008","externalUrl":null,"permalink":"/posts/2008-08-26-we-are-hiring/","section":"Posts","summary":"After everything-but-quiet summer, things got even busier and we need to add more great people to our teams.\nAt the moment we're looking for\n* Junior Java developers\n* Intermediate Java developers\n* Intermediate .Net developers\n* Senior .Net developers\n* Junior Graphics/UI/Multimedia Designer\nSorry - no teleworking, you must be local to apply. If you feel like fitting in - or know somebody in Ottawa that would fit, email Miro at thinknostic dot com ...\n","title":"We are hiring","type":"post"},{"content":"Here is the scoop: I need to provide access to multiple log files spread across multiple directories of multiple machines. For example - the JBoss log files and nohup.out, ATG log files, and so on - so that the testers can see what happened on server side when something looks fishy on front end.\nOne option would be to write a document that contails IP\u0026rsquo;s of the machines, create user accounts, make sure that they have just enough access rights to see the files but not disturb anything else \u0026hellip;\nOther option is to leverage the already installed Python across all the servers. I wish it was Ruby, but one cannot have everything.\nOn each machine, I created directory - e.g.\n~/webaccess\nand made symbolic links to all log files or log directories required.\nThen I placed this python script into the directory:\n#!/usr/bin/python import SimpleHTTPServer import SocketServer # minimal web server. serves files relative to the # current directory. PORT = 9999 Handler = SimpleHTTPServer.SimpleHTTPRequestHandler Handler.extensions_map.update({ \u0026#39;\u0026#39;: \u0026#39;application/octet-stream\u0026#39;, # Default \u0026#39;.out\u0026#39;: \u0026#39;text/plain\u0026#39;, \u0026#39;.log\u0026#39;: \u0026#39;text/plain\u0026#39; }) httpd = SocketServer.TCPServer((\u0026#34;\u0026#34;, PORT), Handler) print \u0026#34;serving at port\u0026#34;, PORT httpd.serve_forever() and started it as\nnohup ./simpleserver.py \u0026amp;\nFrom this moment on, all files linked (actually all files in subtree of server directory) are accessible by going to\nhttp://SERVERNAME:9999/\nwhich shows directory listing for linked files.\nOn one of the machine, I have placed additional file - index.html that contained links to all other server names.\nThanks to this page for inspiration.\n","date":"August 25, 2008","externalUrl":null,"permalink":"/posts/2008-08-25-easy-access-to-log-files/","section":"Posts","summary":"Here is the scoop: I need to provide access to multiple log files spread across multiple directories of multiple machines. For example - the JBoss log files and nohup.out, ATG log files, and so on - so that the testers can see what happened on server side when something looks fishy on front end.\nOne option would be to write a document that contails IP’s of the machines, create user accounts, make sure that they have just enough access rights to see the files but not disturb anything else …\n","title":"Easy access to log files","type":"post"},{"content":"Finally - the new version of Things on iPhone can synchronize with Things on Mac desktop.\nIt actually works - no strings attached. Assumed that:\n1) the WiFi on iPhone is on\n2) iPhone and Mac are on same network (so that Bonjour magic can work)\n3) the Mac Things is running when you start Things on iPhone\nthe synchronization happens automatically and is VERY fast (few seconds max).\nFinally a portable GTD application that works for me :-).\nPS: Things is very nice implementation of GTD. If you are not into GTD cult, do not bother - or try reading this, this and this first ....\n","date":"August 24, 2008","externalUrl":null,"permalink":"/posts/2008-08-24-the-things-bliss/","section":"Posts","summary":"Finally - the new version of Things on iPhone can synchronize with Things on Mac desktop.\nIt actually works - no strings attached. Assumed that:\n1) the WiFi on iPhone is on\n2) iPhone and Mac are on same network (so that Bonjour magic can work)\n3) the Mac Things is running when you start Things on iPhone\nthe synchronization happens automatically and is VERY fast (few seconds max).\nFinally a portable GTD application that works for me :-).\n","title":"The Things bliss","type":"post"},{"content":"Many people recently (including myself) had experiences difficulties with Web access on the iPhone. Quite often the following error message pops up:\nUsually repeating the web page access helps. Sometimes you have to try third time or wait few minutes.\nThis has nothing to do with signal strenght - as you can see, there are 4 bars and 3G is on. I saw it happen on Edge as well. Reseting the phone sometimes helps, but it is hard to say whether because of the reset or time delay ..\nMost people think this is network problem with Rogers data network and I tend to agree. If it was an iPhone or Safari issue, it would not go away with retrying - I think.\nIt also happens in more than just Safari: the weather does not get updates, Mail fails fetching the last state and so on.\nHere are some threads on the issue:\nhttp://discussions.apple.com/thread.jspa?threadID=1622181\u0026amp;tstart=0\nhttp://www.iphoneincanada.ca/forums/showthread.php?p=21624\nIt would not be first time when Rogers would be using paying customers as beta testers of the service. Few years back when hispeed internet was introduced, I remember frequent outages and spending time with their (not so great) techsupport. Eventually, they must have learned how to do it or build up capacities because it went away.\nLet's hope the same happens with the 3G data network. And it better happens quickly, because this service sucks, dear Rogers ...\nIf you are seeing the same issue, please open the ticket with both Rogers and Apple (to create some pressure).\n","date":"August 23, 2008","externalUrl":null,"permalink":"/posts/2008-08-23-rogers-iphone-and-the-dreaded-kcferrordomaincfnetwork-error-302/","section":"Posts","summary":"Many people recently (including myself) had experiences difficulties with Web access on the iPhone. Quite often the following error message pops up:\nUsually repeating the web page access helps. Sometimes you have to try third time or wait few minutes.\nThis has nothing to do with signal strenght - as you can see, there are 4 bars and 3G is on. I saw it happen on Edge as well. Reseting the phone sometimes helps, but it is hard to say whether because of the reset or time delay ..\n","title":"Rogers, iPhone and the dreaded kCFErrorDomainCFNetwork Error 302","type":"post"},{"content":"I have been \"living in a command line\" for last few weeks. Pretty refreshing experience. As result, I had to google a lot, especially when it comes to e.g. subtle differences between tar options on Ubuntu Linux and Open Solaris ... While doing that, I somehow stumbled upon this great writeup on cultural differences between Linux and Windows. Nicely written, no flamewars - obviously pro-Linux, but no Microsoft or Windows bashing and lots of insight. Higly recommended.\nhttp://linux.oneandoneis2.org/LNW.htm\nI really liked the metaphor about Lego cars :-)\n","date":"August 22, 2008","externalUrl":null,"permalink":"/posts/2008-08-22-linux-vs-windows-great-comparison/","section":"Posts","summary":"I have been \"living in a command line\" for last few weeks. Pretty refreshing experience. As result, I had to google a lot, especially when it comes to e.g. subtle differences between tar options on Ubuntu Linux and Open Solaris ... While doing that, I somehow stumbled upon this great writeup on cultural differences between Linux and Windows. Nicely written, no flamewars - obviously pro-Linux, but no Microsoft or Windows bashing and lots of insight. Higly recommended.\n","title":"Linux vs Windows - great comparison","type":"post"},{"content":"Having used Touch 2.0, I managed not to install everything I found in AppStore. Majority of which is crap anyway - people are still learning how to use the platform properly. Pretty soon though, all those flashlights, tip calculators and similar pointless-ware will be replaced by apps that make sense. I hope.\nJust for the reference: here is my iTunes snapshot as of today:\nSome applications are pure time killers (when waiting in line and there is signal to read news online) but some are actually very useful. Few comments to those I actually use are below - actually, first three of the apps are below - I will get back to few more in subsequent posts:\nFacebook\nThis is Facebook as it should be. It actually made me come back to the Facebook. iPhone makes perfect device companion for social network sites: you can update your status in the moment when you actually doing something interesting and see your friends updates at any time, not just while sitting at the computer. You can take photos and upload them right away. And when you are bored or waiting, you can browse messages or pictures of the people you know. This is a good one - try it out:\nUnits\nMain reason I am mentioning it is that this was first app I bought while testing the AppStore purchase system ( the required $0.99 which is less than one half of Grande in Starbucks does not really create any entry barrier ;-)). I wish I had it with me when I was down in the USA last moth. My car does not have second circle for speed with the medevial units they still use I had to keep multiplying by 1.6 to make sure I am within speed limit ...\nRight now, there are just too many unit conversions, but this one does everything I need so I guess I am done with them all. Unless of course there will be an app written by somebody I know (hi Pero ...).\nRemote\nWork of art. Simple, elegant, functional. Allows to pair the iPhone / iPod touch with one or more iTunes libraries on your Macs and use the device as remote control. No line of sight is required - but WiFi must be on. Good for practical jokes by changing somebody's music :-)\n","date":"August 21, 2008","externalUrl":null,"permalink":"/posts/2008-08-21-iphone-3g-first-impressions-applications/","section":"Posts","summary":"Having used Touch 2.0, I managed not to install everything I found in AppStore. Majority of which is crap anyway - people are still learning how to use the platform properly. Pretty soon though, all those flashlights, tip calculators and similar pointless-ware will be replaced by apps that make sense. I hope.\nJust for the reference: here is my iTunes snapshot as of today:\nSome applications are pure time killers (when waiting in line and there is signal to read news online) but some are actually very useful. Few comments to those I actually use are below - actually, first three of the apps are below - I will get back to few more in subsequent posts:\n","title":"iPhone 3G first impressions: Applications","type":"post"},{"content":"I just noticed strange thing: it is most likely unrelated, but it happened right after installing 2.0.2 firmware.\nThe count of updates for AppStore applications is pretty chaotic. You can see different number of updates when looking into different parts of iTunes. I have noticed this cycle repeating for 9 updates, then 8 and so on - here is how it looked when I got down to 3 un-updated apps after few rounds.\nThe overview window shows 2 updates:\nThis is supported with the bottom-right information in the iTunes window:\nBut after I click on the arrow, here is the screen with ONE update:\nHowever - right after clicking on AppStore -\u0026gt; Application updates in the navigation bar:\nI get suddenly 3 updates. And Stanza is NONE of them:\nSo I update all applications, and number of updates indeed disappears:\nSo does the text in bottom right corner:\nAnd finaly, everything is OK.\nSo - what was so special about Stanza ?\n","date":"August 20, 2008","externalUrl":null,"permalink":"/posts/2008-08-20-itunes-appstore-update-chaos/","section":"Posts","summary":"I just noticed strange thing: it is most likely unrelated, but it happened right after installing 2.0.2 firmware.\nThe count of updates for AppStore applications is pretty chaotic. You can see different number of updates when looking into different parts of iTunes. I have noticed this cycle repeating for 9 updates, then 8 and so on - here is how it looked when I got down to 3 un-updated apps after few rounds.\n","title":"iTunes AppStore update chaos","type":"post"},{"content":"It is sooo simple:\n1) Run the app you want to get screenshot of\n2) Press the home button at the same time as On button. Screen will flash white for a sec\n3) Find the picture saved in your photos.\nThis is second amazing thing I have found out about iPhone in last few days. First was hidden button on the headphone mike that can start/stop running iPod music, pick up the ringing phone or (doubleclick) advance to next song. Very useful while walking ...\n","date":"August 19, 2008","externalUrl":null,"permalink":"/posts/2008-08-19-how-to-make-screenshot-of-running-application-on-iphone-3g/","section":"Posts","summary":"It is sooo simple:\n1) Run the app you want to get screenshot of\n2) Press the home button at the same time as On button. Screen will flash white for a sec\n3) Find the picture saved in your photos.\nThis is second amazing thing I have found out about iPhone in last few days. First was hidden button on the headphone mike that can start/stop running iPod music, pick up the ringing phone or (doubleclick) advance to next song. Very useful while walking ...\n","title":"How to make screenshot of running application on iPhone 3G","type":"post"},{"content":"After carrying in my pocket for 3 days, I have decided to get something to prevent my smallest Mac from scratches and breaking when drops (I did drop the iPod touch and it was close call: one of the edges was scratched and slightly damaged).\nIt took some time to decide, but at the end I settled for this one:\nIn white, of course. It is a bit tricky to put it on, but it feels very solid and does not slip.\nRecommended.\nI bought it in one of the two Montreal Apple Store for $24.95\n","date":"August 17, 2008","externalUrl":null,"permalink":"/posts/2008-08-17-good-hard-shell-case-for-iphone-3g/","section":"Posts","summary":"After carrying in my pocket for 3 days, I have decided to get something to prevent my smallest Mac from scratches and breaking when drops (I did drop the iPod touch and it was close call: one of the edges was scratched and slightly damaged).\nIt took some time to decide, but at the end I settled for this one:\nIn white, of course. It is a bit tricky to put it on, but it feels very solid and does not slip.\n","title":"Good hard shell case for iPhone 3G","type":"post"},{"content":"This may be a random event, but here is what happened:\n1) Switch on camera and and take couple of pictures\n2) While camera still on in taking pictures mode, switch off the phone (by the switch on top).\nAfter doing that, about 1.5 hour later I took out the phone to check the emails. Phone was very warm - not the kind of unpleasantly hot you get from Macbook Pro battery when rendering movie on batery power , but still much warmer than ever. Camera was still on. The battery that was two hours ago fully charged was on less than 10%. Strange.\nAnybody else had similar experience ?\nSince that, of course I am careful to switch off the camera first. I think that time is almost ready for 2.1 firmware with the core apps updates, how about that Apple ?\n","date":"August 16, 2008","externalUrl":null,"permalink":"/posts/2008-08-16-how-to-kill-iphone-battery-in-less-that-2-hours/","section":"Posts","summary":"This may be a random event, but here is what happened:\n1) Switch on camera and and take couple of pictures\n2) While camera still on in taking pictures mode, switch off the phone (by the switch on top).\nAfter doing that, about 1.5 hour later I took out the phone to check the emails. Phone was very warm - not the kind of unpleasantly hot you get from Macbook Pro battery when rendering movie on batery power , but still much warmer than ever. Camera was still on. The battery that was two hours ago fully charged was on less than 10%. Strange.\n","title":"How to kill iPhone battery in less than 2 hours","type":"post"},{"content":"One of the many things that I never did before was actually customizing the phone. Neither of the songs that I really liked for ringtone (and were unique enough) were available of course. I found this website: http://audiko.net/en.html that allows to take an MP3 (one that you legally own, of course) and convert it to ringtone.\nHere is how it works:\n1) Find a suitable MP3\n2) Go to above website, upload MP3\n3) In editor, select the start and end sequence of the melody - you can listen to it before you finalize\n4) Press 'Create Ringtone' and download it\n5) Import to iTunes\nCould not be simpler than that.\nDisclaimer: Uploading MP3 (or even creating them by ripping the CD's) may be illegal in the country you live. I do not recommend or suggest you should do it - I am merely describing a technical process of data transformation and take absolutely no responsibility for any troubles or issues related to that you may get yourself into.\n","date":"August 15, 2008","externalUrl":null,"permalink":"/posts/2008-08-15-create-own-ringtones-for-iphone-3g/","section":"Posts","summary":"One of the many things that I never did before was actually customizing the phone. Neither of the songs that I really liked for ringtone (and were unique enough) were available of course. I found this website: http://audiko.net/en.html that allows to take an MP3 (one that you legally own, of course) and convert it to ringtone.\nHere is how it works:\n1) Find a suitable MP3\n2) Go to above website, upload MP3\n","title":"Create own ringtones for iPhone 3G","type":"post"},{"content":"Mac #3 in our household (after Macbook and Macbook Pro):\nThe beautiful 20\", 4GB RAM, 750 GB HDD, about to replace the old tablet my wife was using and as school computer.\nPS: In the excitement of the event I forgot to publish this so it was sitting in Drafts until Saturday. Publishing with original date of the event - for the record. Funny enough, it is almost precisely the 10 birthday of the original iMac.\n","date":"August 14, 2008","externalUrl":null,"permalink":"/posts/2008-08-14-it-arrived/","section":"Posts","summary":"Mac #3 in our household (after Macbook and Macbook Pro):\nThe beautiful 20\", 4GB RAM, 750 GB HDD, about to replace the old tablet my wife was using and as school computer.\nPS: In the excitement of the event I forgot to publish this so it was sitting in Drafts until Saturday. Publishing with original date of the event - for the record. Funny enough, it is almost precisely the 10 birthday of the original iMac.\n","title":"It arrived","type":"post"},{"content":"Does it work ?\nWe'll see - blogging from the train\nAll the above - including the picture was created and posted on iPhone, using the Wordpress Application (thanks to Peter K. to make me aware of it). I have not used it much, but the first impressions are certainly positive: it works and allows to compose reasonable blog entry, including images on the go. As long as you are fast typist on the miniature keyboard - which I am not, so I will still prefer for longer text the great comfort of Macbook Pro keyboard (probably the best keyboard I have ever used so far). But it can be handy for short posts so I am going to keep it. Price - zero Alexes ((C) Macbreak weekly) == $0. Free. Not Libre, not opensource - thanks anyway ...\nIf you want just to post images and have SmugMug account, there is another free app that I have been using quite a lot. Mostly because there is no way how I can use my 6GB allocated data transfer montly limit ;-)\nThe application is named SmugShot and allows to take picture and upload it to dedicated gallery on SmugMug. I have been taking lots of pictures and posting them into my Smugshot Gallery - which is (unlike most of other pictures) publicly viewable. See for yourself - the images are nothing breathtaking, but if you have not seen SmugMug, look at it - IMHO it is very worth of the price.\n","date":"August 12, 2008","externalUrl":null,"permalink":"/posts/2008-08-12-test-of-the-wordpress-and-smugshot-applications-for-iphone/","section":"Posts","summary":"Does it work ?\nWe'll see - blogging from the train\nAll the above - including the picture was created and posted on iPhone, using the Wordpress Application (thanks to Peter K. to make me aware of it). I have not used it much, but the first impressions are certainly positive: it works and allows to compose reasonable blog entry, including images on the go. As long as you are fast typist on the miniature keyboard - which I am not, so I will still prefer for longer text the great comfort of Macbook Pro keyboard (probably the best keyboard I have ever used so far). But it can be handy for short posts so I am going to keep it. Price - zero Alexes ((C) Macbreak weekly) == $0. Free. Not Libre, not opensource - thanks anyway ...\n","title":"Test of the Wordpress and Smugshot applications for iPhone","type":"post"},{"content":"This is what I get for last hour or so:\nIt is so frustrasting when something taken for granted suddenly disappears ... and at the same time quite scary how dependent we became on it.\nLet's keep our fingers crossed and hope for GMails early return\n","date":"August 11, 2008","externalUrl":null,"permalink":"/posts/2008-08-11-gmail-is-down-sky-is-falling/","section":"Posts","summary":"This is what I get for last hour or so:\nIt is so frustrasting when something taken for granted suddenly disappears ... and at the same time quite scary how dependent we became on it.\nLet's keep our fingers crossed and hope for GMails early return\n","title":"Gmail is down - Sky is falling ....","type":"post"},{"content":"There is great site 10 minute mail - which does exactly what it says. Provides you an email address that lives for 10 minutes and then evaporates. For this 10 minutes, you can read any email sent to it on the web page - and eventually renew it for another 10 minutes. Great way how to beat spammers and other email address collecting sites ...\nHere is how it looks like.\nSite like this obviously needs to live on advertisement. Do you see the irony ? What it offers is actually spamming tool. Now I am not sure whether this is a proof of deep insight or stupidity on advertiser side - or a sign of good sense of humor on the side of the OneMinute Email host :-)\n","date":"August 11, 2008","externalUrl":null,"permalink":"/posts/2008-08-11-irony-of-anti-spam-site-selling-spam-tools/","section":"Posts","summary":"There is great site 10 minute mail - which does exactly what it says. Provides you an email address that lives for 10 minutes and then evaporates. For this 10 minutes, you can read any email sent to it on the web page - and eventually renew it for another 10 minutes. Great way how to beat spammers and other email address collecting sites ...\nHere is how it looks like.\n","title":"Irony of anti-spam site: selling spam tools","type":"post"},{"content":"This is what I got trying to track my recent purchase from Apple Store ...\nThat may not be the most useless error message ever seen on Web but it comes pretty close ... One would expect a bit more professional treatment from such big company ...\nWhy does a company that puts so much emphasis on user experience and perception (like Apple) pick business partners (such as this one - or one certain Canadian wireless provider company running the GSM network) that suck so much that it ruins this perception ? Are the other companies even worse ? Hard to imagine ...\n","date":"August 10, 2008","externalUrl":null,"permalink":"/posts/2008-08-10-example-of-useless-error-message/","section":"Posts","summary":"This is what I got trying to track my recent purchase from Apple Store ...\nThat may not be the most useless error message ever seen on Web but it comes pretty close ... One would expect a bit more professional treatment from such big company ...\nWhy does a company that puts so much emphasis on user experience and perception (like Apple) pick business partners (such as this one - or one certain Canadian wireless provider company running the GSM network) that suck so much that it ruins this perception ? Are the other companies even worse ? Hard to imagine ...\n","title":"Example of useless error message","type":"post"},{"content":"A gem from Merlin's twitter feed. I found it being both hilariously funny as well as wildly applicable :D\nThere's nothing wrong with me that couldn't be fixed by a little exercise, some discipline, and a weekend at the Dog Psychology Center.\nMerlin Mann\n","date":"August 9, 2008","externalUrl":null,"permalink":"/posts/2008-08-09-quote-of-the-day-14/","section":"Posts","summary":"A gem from Merlin's twitter feed. I found it being both hilariously funny as well as wildly applicable :D\nThere's nothing wrong with me that couldn't be fixed by a little exercise, some discipline, and a weekend at the Dog Psychology Center.\nMerlin Mann\n","title":"Quote of the day","type":"post"},{"content":"Phone\nThe sound of the iPhone is much clearer and generally better than my old RAZR.\nWhat I really like is a built-in microphone in headphones that allows making and answering calls without holding phone next to your ear. Second is handling of the incoming call while listening to podcast or music: it fades aways and after finishing the call, it slowly fades back in. Very nicely done.\nBut the best phone feature is seamless integration with my address book, which thanks to synchronization that works very well always the same as address book on my Mac. It offers classic \"wheel search\", list of recent calls, list of favorites and dial keyboard. What is really awesome is the easy to add or update information: for example, you receive a call from a friend that just got a new phone. After hanging up, with single click on the recent entry you can assign the just received number to an existing contact. And it is always that single address card you use - with address (that you can show in Google map with another click) or email addresses that you can fire up with single click..\nBtw, this integration makes GMail on iPhone better email client than on desktop within the browser, because here you use (and can enhance) your address book, not the separate Google Contact list - which is, despite the recent improvents still not on par with address book application.\nCompare that to the \"hashtable\" I had on RAZR where people with 3 phone numbers had three address book entries (e.g. Igor mobil, Igor work, Igor home) with no way how to \"merge\" them ...\nBattery life\nBattery life is considerably shorter than I was used from the Touch, which I had to recharge once every 4 days (depending on weather and consequently amount of walking done). This declined sharply to 1.5-2 days when I left the WiFi on.\nThe iPhone needs his energy fix pretty much every day, if you use it heavily, maybe even more than that.\nThe Settings in General section shows you both actual use time as well as standby time. I run with location services on, WiFi mostly off (except for iTunes at home) and cellular on 3G. I also check emails, maps etc quite frequently, take pictures like maniac (its new toy after all) and listen to the podcasts or music a lot. In average day, I get usually 4-7 hours of usage (meaning that phone is not in standby but doing something) - like playing a podcast and that usually drains the battery.\nI may need to review that after I get few more full cycles out - full charge and full discharge and test the standby performance ... as soon I manage to keep my hands of it ...\nSo far I have seen anywhere between 5 and 9 hours of use - really depends how much you are walking with screen on and observe the blue glowing dot to move - this drains battery quite a bit. Also watching video (as expected) is heavy and WiFi as well.\nThe battery life improves when you switch off 3G and bear the sluggishness of EDGE connectivity. It is still usable but much less fun. Right now, sitting in train to Montreal, EDGE is all have here between Alexandria and Coteau, and I call that lucky because we have been going through several No Service dark holes ...\n","date":"August 7, 2008","externalUrl":null,"permalink":"/posts/2008-08-07-iphone-3g-first-impressions-phone-battery-life/","section":"Posts","summary":"Phone\nThe sound of the iPhone is much clearer and generally better than my old RAZR.\nWhat I really like is a built-in microphone in headphones that allows making and answering calls without holding phone next to your ear. Second is handling of the incoming call while listening to podcast or music: it fades aways and after finishing the call, it slowly fades back in. Very nicely done.\nBut the best phone feature is seamless integration with my address book, which thanks to synchronization that works very well always the same as address book on my Mac. It offers classic \"wheel search\", list of recent calls, list of favorites and dial keyboard. What is really awesome is the easy to add or update information: for example, you receive a call from a friend that just got a new phone. After hanging up, with single click on the recent entry you can assign the just received number to an existing contact. And it is always that single address card you use - with address (that you can show in Google map with another click) or email addresses that you can fire up with single click..\n","title":"iPhone 3G first impressions: Phone, Battery Life","type":"post"},{"content":"This Sunday, as every first Sunday in month we had regular Bytown Mac User Group meeting at usual place - Patty Bolands Pub at the Market. It was great meeting because we had many newcomers - both to the group as well as to the platform, including very fresh Mac switch - a happy owner of 24 hours old Macbook Pro.\nThe presentations were very suited for the audience of newcomers, especially Katheryne's demo on customizing the Mac. She was kind enough to send the links to the talk (the mailing list). I think that the links are very useful for wider audience than just the ByMUG folks, so I will repost them here ... withour her permission, but in here very own words :-)\nThanks again for your attention during my presentation - these are the times I am very happy I chose the MBP over the MacBook :) Here are the links as promised:\nHardshell cases:\n- InCase \u0026lt;http://www.goincase.com/products/detail/15-hardshell-case-cl57123\u0026gt;\n- Speck \u0026lt;http://www.speckproducts.com/products/seethru/macbook-pro-15/25\u0026gt; (Warning: Flash. Eugh.)\nFrom Apple:\n- Icons, screensavers, etc. \u0026lt;http://www.apple.com/downloads/macosx/icons_screensavers/\u0026gt; Don't be afraid to click around and find out about other downloadable goodies.\nScreensavers:\n- Phantom Butterflies, Strands, Filigree, Iota, Scattered Flurries (aka snow!), etc. \u0026lt;http://www.whiteknightlogic.net/\u0026gt; \u0026amp; Ignis Fatui (one of my faves) \u0026lt;http://www.whiteknightlogic.net/code.php?5\u0026gt;\n- Anèmona \u0026lt;http://uri.cat/software/Anemona/\u0026gt;\n- Fishes, Matrix code, Jigsaw puzzle, etc.: \u0026lt;http://www.uselesscreations.com/\u0026gt;\n- X-Galaxy \u0026lt;http://www.multithemes.com/\u0026gt; (The purpley whooshy one)\nWallpapers sites:\n\u0026lt;http://interfacelift.com/wallpaper_beta/downloads/date/any/\u0026gt;\n\u0026lt;http://usingmac.com/2008/7/28/200-mind-blowing-nature-wallpapers\u0026gt;\n\u0026lt;http://www.pixelgirlpresents.com/desktops.php\u0026gt;\n\u0026lt;http://www.digitalblasphemy.com/freegallery.shtml\u0026gt;\nIcon sites:\n\u0026lt;http://www.iconarchive.com/\u0026gt;\n\u0026lt;http://interfacelift.com/icons-mac/\u0026gt;\nDeviantArt has a lot of artists putting up amazing icon sets, like this one: \u0026lt;http://rimshotdesign.deviantart.com/art/NOD2-93263843\u0026gt;\nCustom folder creators:\n\u0026lt;http://www.samuco.net/Downloads/Coloured_Folder_Creator.html\u0026gt;\n\u0026lt;http://macdownloads.pbwiki.com/Coloured-Folder-Creator\u0026gt; (Oops, I think the download link is broken. You can probably still download it from the host site.)\nOther cool stuff:\n- Adium (instant messaging application): \u0026lt;http://adiumx.com/\u0026gt;\n- Wallsaver (screensaver as wallpaper): \u0026lt;http://www.wallsaverapp.com/\u0026gt;\n- iConiCal (different colors for your iCal icon): \u0026lt;http://www.blocksoft.net/iconical.html\u0026gt;\n- CandyBar (to change icons, app icons, dock, etc. 15-day trial with 250 icon capacity, 29$ for full version): \u0026lt;http://www.panic.com/candybar/\u0026gt; and Iconfactory: \u0026lt;http://iconfactory.com/freeware/icon\u0026gt;\n- LiteIcon (free icon restore/change app): \u0026lt;http://www.freemacsoft.net/LiteIcon/\u0026gt;\n- Shapeshifter \u0026lt;http://unsanity.com/haxies/shapeshifter\u0026gt; to use themes (GUIs) \u0026lt;http://interfacelift.com/themes-mac/\u0026gt; built using ThemePark \u0026lt;http://www.geekspiff.com/software/themepark/\u0026gt;\n- The dock I was using today, Alu Curved 3D: \u0026lt;http://macthemes2.net/forum/viewtopic.php?id=16787502\u0026gt; (MacThemes - learn to love this site if you want to sleekify your Mac even more!). Other docks from this site: \u0026lt;http://macthemes2.net/forum/viewtopic.php?id=16784360\u0026gt; and \u0026lt;http://macthemes2.net/forum/viewtopic.php?id=16782319\u0026gt; (this link has a dock with instructions for a manual installation of a new Simple Dock - left/right).\nThanks, Katheryne and Glenda for preparing the demos - and sorry for the projector cables mix up ...\nSome shots from the meeting (taken on my shiny new whitey iPhone ;-)\n","date":"August 5, 2008","externalUrl":null,"permalink":"/posts/2008-08-05-bymug-meeting-august/","section":"Posts","summary":"This Sunday, as every first Sunday in month we had regular Bytown Mac User Group meeting at usual place - Patty Bolands Pub at the Market. It was great meeting because we had many newcomers - both to the group as well as to the platform, including very fresh Mac switch - a happy owner of 24 hours old Macbook Pro.\nThe presentations were very suited for the audience of newcomers, especially Katheryne's demo on customizing the Mac. She was kind enough to send the links to the talk (the mailing list). I think that the links are very useful for wider audience than just the ByMUG folks, so I will repost them here ... withour her permission, but in here very own words :-)\n","title":"ByMUG meeting - August","type":"post"},{"content":"continued from here\nEmail\nMy email information was transferred from Touch as part of the activation process and started to work right away. Very good and functional user interface.\nI also found the mobile Google page (http://www.google.com/m) to be very useful - it adds easy access to small screen optimized versions of the Calendar and Reader. I use Reader a lot, the best feature being that articles I read on ANY device (MBP, Linux desktop, iPhone or even some of the many VM's I am using)\nwill be marked as read ...\nLocation Services\nI went for a walk to closest Starbucks to test the maps and GPS. It is pretty scary how precise it can be.\nNot 100% of the cases - sometimes for no particular reason, it does not find you with better precision than you would expect from cell towers, but in 99%, it is bang on. Within maybe 10-20 meters. Even more impressive when you walk and see the blue glowing ball move on the map.\nFrom applications out there I have not yet find the \"ultimate walker companion\" - an app that would take a snapshot of my location in predefined interval (1 min - 5 min) and save it to trail, then allow to upload the trail to Mac and show it on Google Map. Some come close, but I think somebody will write this one some day :-). I tried out 'I Am Here' - free app that takes your location and sends it to email recipient.\nWould be great, if it had an option to pre-define the recipient and have single button send.\nWeb browsing\nThe mobile Safari is actually pretty good. Very readable, good ergonomics. Few features that I miss is easy\nway how to access delicious bookmarks (add new mark). The speed on 3G network is pretty good, if you switch 3G off (or get out of coverage) and downgrade to EDGE the browsing is much less fun ...\nI have created home page bookmarks for most of site I access often: Google mobile home, DZone, Digg, Safari. Google Documents is partially usable - you can read most of the documents (the spreadsheet cannot be sized) but their are not editable. Google Notebook does not work either.\nOn a positive note, Safari books online work on Safari very well. This with Dzone + Reader = never more be bored while waiting or traveling. The limit of maximum 8 pages is sort of annoyance - although I understand why it makes sense to have some limit ...\nCamera\nMuch better than the RAZR, which does not say much. But actually, it works reasonably good in various\nlightning conditions and produces pictures that are reasonably good for documentary purposes.\nDisclaimer: I am DSLR snob, contemplating upgrade to D300 as soon as the D700 pushes price a bit down, so there is no comparing with something that has miniscule piece of glass instead of lens ;-\nData plan\nI purchased the add-on 6 GB / month plan for $30. Kind of expensive and as many others, I was strongly feeling that for that price, it should be unlimited.\nBut for all practical reasons, this is pretty much same as unlimited. 6 GB means about 200 MB a day and even with lots of surfing, YouTube and documents reading / emailing it's hard to go over 100 MB a day more likely 20-30 MB. You will simply not have enough battery power to burn the 200 MB a day ..\nSo the data plan works just OK and I can use apps like Google Maps with satelite view without worrying about paying dearly to look at than place in Calabria my sister went for vacation to ...\nFrom applications - some can be pretty easily bandwith hog. Good candidate for it is SmugMug - free app that uploads your photos to SmugMug account - I am playing with that (see for yourself if you want to see the iPhone camera resolution - or get bored as I was shooting randomly everything around ...)\nto be continued\n","date":"August 4, 2008","externalUrl":null,"permalink":"/posts/2008-08-04-iphone-3g-first-impressions-email-web-camera-gps-data-plan/","section":"Posts","summary":"continued from here\nEmail\nMy email information was transferred from Touch as part of the activation process and started to work right away. Very good and functional user interface.\nI also found the mobile Google page (http://www.google.com/m) to be very useful - it adds easy access to small screen optimized versions of the Calendar and Reader. I use Reader a lot, the best feature being that articles I read on ANY device (MBP, Linux desktop, iPhone or even some of the many VM's I am using)\nwill be marked as read ...\n","title":"iPhone 3G first impressions: Email, Web, Camera, GPS, Data Plan","type":"post"},{"content":"There more than enough reviews and opinions on the coolest gadget in the telephony space so what is point o adding another one ? I was originally quite anti-iPhone anti-Rogers for - IMHO - pretty strong reasons, so it is interesting to review them and see how they survived the reality check.\nThat maybe not be the strongest reason ... but am going to do that anyway.\nActivation\nI have ordered the phone by calling the 1-888-ROGERS1 and as I mentioned, the shopping experience was for a change a great one ... That was Tuesday morning and to my big surprise, the phone was delivered n Thursday afternoon.\nI surpressed the urge return to Ottawa (I was in Montreal until end of week) and could get to the setup only on Friday evening. It was good to find that I have received what I ordered - white 16 GB version ...\nThe Apple portion of the activation was excellent user experience. I plugged the phone to my Macbook Pro and that was it. It recognized it, offered option to restore last backup from my iPod Touch, which loaded not only all podcasts and music, but also all applications. Very nice. 9 out of 10 (would be 10, if the whole process was a bit faster)\nThe phone setup (read Rogers) part was pretty lame, though. I had to call the Rogers again, and - unlike when I wanted to spend money with them - I was less than happy. First, wait time everywhere until you get somebody on the line. I do not quite understand what is the point of annoying voice guidance computer system, when you mostly end up by wrong person anyway.\nFirst CR was neither friendly nor competent, after collecting all my data redirected me to different department. Another long wait. The second person was also unable to solve it, but at least she was genuinely trying to be helpful and started to get some technical rep on line. It took another 20 minutes (two rounds Spider Solitair in Windows VM). After the tech rep became available, I had to take out my SIM, read the serial number and my service was switched in less than 5 minutes. Globally, Rogers 3 out of 10 - just because the tech rep was actually pretty good.\nTo be continued\n","date":"August 3, 2008","externalUrl":null,"permalink":"/posts/2008-08-03-iphone-3g-first-impressions-activation/","section":"Posts","summary":"There more than enough reviews and opinions on the coolest gadget in the telephony space so what is point o adding another one ? I was originally quite anti-iPhone anti-Rogers for - IMHO - pretty strong reasons, so it is interesting to review them and see how they survived the reality check.\nThat maybe not be the strongest reason ... but am going to do that anyway.\nActivation\nI have ordered the phone by calling the 1-888-ROGERS1 and as I mentioned, the shopping experience was for a change a great one ... That was Tuesday morning and to my big surprise, the phone was delivered n Thursday afternoon.\n","title":"iPhone 3G first impressions: Activation","type":"post"},{"content":"The http://www.techscreencast.com/ - lots of great content about operating systems, tools, technologies, languages and generally \"stuff that matters\"(TM).\nRecommended ...\n","date":"August 2, 2008","externalUrl":null,"permalink":"/posts/2008-08-02-great-technical-screencasts/","section":"Posts","summary":"The http://www.techscreencast.com/ - lots of great content about operating systems, tools, technologies, languages and generally \"stuff that matters\"(TM).\nRecommended ...\n","title":"Great technical screencasts","type":"post"},{"content":"I was holding off for over two weeks, decided not go with that outrageous iPhone voice/data racket. Even trying to encourage people to wait in a hope the demand will be weak and Rogers will bend and lower the rates.\nOnly, it was not. I mean demand. iPhones seems to be selling better than beaver tales on Dow's Lake during sub minus twenty sunny skating Saturday. Especially the 16 GB ones.\nNow it's over. I ordered white 16 GB iPhone yesterday.\nIt's all Gabo's fault. After playing a bit with the darn thing, I can resist no more. It is after all more than just iPod touch with more hardware. Four killer features from my very private point of view:\n1) GPS with Google maps. So valuable especially now when I spend more time in Montreal than in Ottawa and walk around during evenings and lunch breaks...\n2) Internet access. All my stuff is in the cloud - notes, documents, contacts, emails. With 3G or even Edge it is only 1 second and few clicks away. So much faster than getting notebook out of backpack. Not speaking of not needing WiFi to do so - very useful while sitting in the train. Btw, ViaRail, your WiFi is so unusable ....\n3) camera that allows taking only slighly bad pictures. Big upgrade from Motorola where pictures were just plain terrible / hardly usable. Getting them off the phone happens automagically and they end up in proper place - iPhoto, without waiting 10 minutes for bluetooth sync ...\n4) Address book synchronization. Finally I will be able to dial from same database that is on my Mac - without holding iPod touch in one hand and phone in other, typing in the number I found on Touch. Yes, I did try to sync RAZR with computer. Three times. It consistently failed and wiped out Motorola twice and Address book once (no damage thanks to Time Machine ;-))\nAll this is worth spending 30 more bucks a month for 6 GB data plan. Gabo discovered it is more than plenty even if you surf a lot and listen to internet radio 2-3 hours a day. I hate the idea giving Rogers more of my money, but, as Tony Soprano would put it: \"What are'ya gonna do ?\". Maybe I can find something to cancel to lower the bill - like some cable package. Who needs TV when there is YouTube and Google Video :-).\nAs added benefit, my daughter is very happy to be getting the Touch really soon now ;-)\nAnd by the way, once for a change talking to the Rogers sales person was quite pleasant experience. Too bad I did not write down her name - but she was really nice. What a change after that groups of obnoxious morons that used to call me regularly to offer HomePhone :-)\n","date":"July 30, 2008","externalUrl":null,"permalink":"/posts/2008-07-30-iphone-3g-i-surrender/","section":"Posts","summary":"I was holding off for over two weeks, decided not go with that outrageous iPhone voice/data racket. Even trying to encourage people to wait in a hope the demand will be weak and Rogers will bend and lower the rates.\nOnly, it was not. I mean demand. iPhones seems to be selling better than beaver tales on Dow's Lake during sub minus twenty sunny skating Saturday. Especially the 16 GB ones.\n","title":"iPhone 3G - I surrender","type":"post"},{"content":"It was very interesting to observe during last few weeks - since WWDC announcement - the wave of expectations building up here in Canada. After all, we will finally officially have the iPhone and will be allowed to join the family of first-category nations, legally iPhonized, blessed by his Steveness himself. Selection of Rogers as carrier was no surprise. Rogers is only company that (IMHO) actually can run 3G iPhone - at least around here in Ontario / Quebec. You see, here in True North, we do not really have anything remotly resembling true competition in telecom space. Nor we have a reasonably good telecoms selling the phone service - only bad, really bad and terrible.\nMany speculations were published about pricing, and when it was made official few days ago, public outroar of disapproval happened. The pricing published here was so bad, that quickly on-line petition started at the website ruinediphone.com, which signed by over 60000 people. Pretty large number, considering the nation of 30 milion. The sentiment of the comments on the site is well expressed by the fact that another URL which redirects you to the site is http://f***yourogers.com/ - try it out :-).\nTwo days ago, there seems to be some announcement that for $30 more, you can get 6 GB data plan on top of your existing voice plan with Rogers. That made many people quite happy and probably many more decided to buy after all. But was it really good news and did the petition really forced large company to backpedal ? Does democracy work in business world ?\nHere is my cynical view of what could have just happened. Disclaimer (for the lawyers and themalike): this is pure fiction and any resemblance to real life event is purely accidental.\nAssume that you are in charge of marketing for a company R that is about to sell product P and wants to get as much as possible money over the fair price (which includes reasonable margin) N. Your goal is to sell for double that price - 2*N.\nWhat you do is announce price plans quoting 3*N and wait for unhappy customer feedback. You fuel that sentiment, so soon many more people are aware of that and word of mouth spreads. You even help to grow the sentiment in the website http://ruinedP.com/ and see happily how more and more people get involved.\nThen, few days before launch, you \"beg down\", and announce the big price break - down to 2*N. Sentiment swings, and many people are now happy to pay what is in reality outrageous sum of money for the P. And because of the campaign and petition, many more people now know about the product and may consider buying - after all, they are about to save big after the price break, aren't they ? And you can still in wiggle out of the promised break by fine-print rules, ifs and whens ....\nYes, you get some really bad sentiment and bad publicity - but it is publicity and it is free :-). Many newspapers and channels (even those owned by you) reported on that. And, if you get lucky, maybe even some eager-beaver politicians may take the bait and join the game \"to defend interest of the public\".\nBut back to reality: on Friday, when the sale starts, we will see how many people will go and buy.\nI hope that as few as possible. Because even after the price \"break\" (which we still do not know if and how it will be applied because Rogers site still shows old pricing info), it is still a bad deal compared to the USA.\nThe amount of money you pay is actually much higher and is cleverly hidden is variety of fees - system access, value pack fees, and just-because-we-can-we-will-charge-you-pack fees. This way the cheapest 60 dollar plan is more like 85 / month and the more likely 100+ month. Which means that over lifetime you will pay 300 for the phone, 35 activation plus 3600 for monthly fees - over $4000. And that, my friends is lot of money for giving up the freedom to be inaccessible by email and have possibility to spend even more time on the web ...\nIf you are developer, 4000 bucks buys you a Mac Pro, Macbook Pro plus Mac Mini, or about 6 Windows desktop PC's. If you are not a geek (which makes me wonder - why are you then reading this blog ;-) ), $4000 is nice escape from frozen Canadian winter for you and your family to warm Caribbean ...\nWithout options to choose from and any competition, all you can do is to vote with your dollars. Because, honestly, your dollars are the only thing Rogers is interested in. I am their customer for over 10 years so I have some first hand experience.\nVoting means: Do not buy. Wait.\nThe ONLY thing that will drive price down is lack of demand. Or competition.\nIf you absolutely MUST have iPhone, you can still \"vote\" - cancel some other Rogers services or switch them to competition: other cell phones, internet, TV - and let Rogers KNOW that you are going away and why. In worst case, the customer retention department will kick in and you can get some freebies :-) Because unlike with iPhone, here you have some alternatives.\nUnfortunately, switching is always an inconvenience for the end user and none of the competitors is much better (sometimes quite a lot worse) than Rogers, so it is really up to you how far are you willing to go in order to send a message.\nOr - if you are mainly after the new platform and mobile apps, you can get iPod touch and get most of the experience - minus phone and minus the montly fees for less than subsidized iPhone price.\nI personally will wait. I have iPod Touch, so I am looking forward to new apps. And I will re-evaluate the iPhone need after all you, my impatient friends can share the news about your montly bills and how much you actually shot over the ridiculous amounts of data bandwidth in them...\n","date":"July 10, 2008","externalUrl":null,"permalink":"/posts/2008-07-10-rogers-iphone-and-conspiracy-theory/","section":"Posts","summary":"It was very interesting to observe during last few weeks - since WWDC announcement - the wave of expectations building up here in Canada. After all, we will finally officially have the iPhone and will be allowed to join the family of first-category nations, legally iPhonized, blessed by his Steveness himself. Selection of Rogers as carrier was no surprise. Rogers is only company that (IMHO) actually can run 3G iPhone - at least around here in Ontario / Quebec. You see, here in True North, we do not really have anything remotly resembling true competition in telecom space. Nor we have a reasonably good telecoms selling the phone service - only bad, really bad and terrible.\n","title":"Rogers, iPhone and Conspiracy Theory","type":"post"},{"content":"I still remember back in 2003/2004 when Rod Johnson wrote his books \"J2EE Design and Development\" and \"J2EE programming without EJB\" and presented his POJO based inversion of control framework - at that time, still packaged as com.interface21.* - that eventually evolved to Spring Framework.\nIdea of composing J2EE application from basic Java Beans, that were instantiated by the core container that managed their lifetime and resolved references was for most people really an eye opening experience, true Aha! moment and completely new world discovery. Everybody I knew was happy and excited about it. I was also happy and excited - not as much because of the novelty, but because of seeing a great design ideas I saw before in closed source implementation to re-appear in open source world.\nThe place I have seen the excellent embodyment of the \"core IoC / DI container\" was an application server Dynamo created by company named ATG (Art Technology Group). ATG wrote the DAS (Dynamo Application Server) whose kernel - container named Nucleus was providing very similar services than Spring container. It also provided lot of added values on top of that: personalization layer, scenario server, portal and administration. In 2002, we at Montage have just delivered one major public sector system based on ATG and second even bigger ATG system was well on the way.\nNow I am NOT suggesting at all there is any idea transfer between ATG and Spring framework - either way. These design principles were known in research papers since 1980-ies and (as many today's great trends) originates from Smalltalk. It was only matter of time who will implement it properly in Java and when. Both ATG and Spring, coming from different angles created quite different systems. One is open and free and pretty much accepted standard. The other is way more powerful and mind bogling toolset - in its current form it is probably the most comprehensive and most powerful eCommerce solution in Java space currently available. Alas, it is not widely known, unless you happen to be working in implementing personalized eCommerce sites in 10-100+ million dollar revenue range.\nIt is very interesting to look at the places where they differ and the consequences of the different decisions for developing in either of the environment. I have decided to publish few blog entries on this, for several reasons:\n1) From technology perspective, ATG platform is very interesting and innovative and lots of ideas and design principles used can be very useful in general application design.\n2) The company - ATG - is probably one of the most unknown and unappreciated Java innovator and pioneers. These guys more or less invented the JSP in its predecessor form - JHTML. They were very first I have seen to have workable IoC container - back in year 2000 and their ideas of \"droplets\" and servlet beans certainly made me say \"wow!\" several times ...\n3) Talking to developers that came to the ATG platform recently, I have sensed the sentiment \".. yeah, yet another Spring knock-off framework \". I am big admirer of Spring, but let's face it: ATG certainly did not get any inspiration from Spring, unless they have a time machine hidden somewhere in their Boston HQ. If the idea-crosspolination happened (and I am NOT saying it did - I simply do not know), it could have been only the other way.\n4) After using mixture of open source technologies and commercial solutions in quite a few projects of various size (from small to humongous) I gained some experience and appreciation of advantages and weak points of each of them and I'd like to share them.\nBefore I start, one disclaimer: Thinknostic is ATG partner and has worked on / is actively working on several ATG projects. Obviously, we are interested in success of these projects :-) and therefore we do have vested interest in success of ATG as platform and indirectly in success of ATG as a company. We are however not shareholders of ATG stock or do not get any incentives for spreading word or encouraging ATG sales (with obvious exception of somebody buying ATG platform and hiring us to help them with implementation). The sole reason for this and future blog posts is very interesting technology behind it. As you hopefully will see, I will try to be objective and highlight the strengths as well as weaknesses of both solutions - Spring's as well as the ATG stack.\n","date":"July 1, 2008","externalUrl":null,"permalink":"/posts/2008-07-01-the-most-underappreciated-java-pioneers/","section":"Posts","summary":"I still remember back in 2003/2004 when Rod Johnson wrote his books \"J2EE Design and Development\" and \"J2EE programming without EJB\" and presented his POJO based inversion of control framework - at that time, still packaged as com.interface21.* - that eventually evolved to Spring Framework.\nIdea of composing J2EE application from basic Java Beans, that were instantiated by the core container that managed their lifetime and resolved references was for most people really an eye opening experience, true Aha! moment and completely new world discovery. Everybody I knew was happy and excited about it. I was also happy and excited - not as much because of the novelty, but because of seeing a great design ideas I saw before in closed source implementation to re-appear in open source world.\n","title":"The (most ?) underappreciated Java pioneers","type":"post"},{"content":"A comment got to me via friend mentioning why am I suddenly so negative about Apple and Macs, which quite surprised me. True, I have had some serious hardware issues in first two weeks of June, but this negative event was about as much positive experience as hard disk crash can be.\nThinking back what I have learned and discovered from this:\n- Time Machine actually works\n- it pays to plug in the firewire disk with Time Machine backups every day - the two second operation saves a lot of time in long run\n- Carbon Copy Cloner is fantastic tool that makes creating bootable copy of your system disk as easy as possible\n- I can easily use multiple bootable disks with various versions of OS-X, not only for backing up but also for trying out new things / installs - a kind of \"VM on a disk\"\nThe most pleasant discovery is that separation of system files and user data actually works in OS-X. Before, when I had to reinstall Windows, even when I had backup of my data files, it was always a pain because the only way how to get back customizations of installed applications was to reinstall them and re-customize. If the application supported something like export of customizations (e.g. Eclipse \"Export Settings\") or had config files and I was lucky to export these or backup copy after each change, it sort of worked. Sometimes. But if application stored the settings in Registry, good luck. IMHO, if there were a competition for most stupid and disastrous software idea, I bet that Windows Registry would get a medal ...\nWhat I did kind of lost trust in, are hard disks, especially high capacity notebook size drives. I am currently reviewing my backup procedures across all systems. I have created bootable clone of my daughter's Macbook hard drive - just in case and start serious think about buying Drobo later this year.\nBut on operating system side, I am happily staying with Apple and Macs. It is not perfect solution and is certainly not as rock solid and secure as Apple would like the world to believe - the last year record of security flaws, crowned with latest discovery of first trojan and root access hole in ARD proves it more than enough. But it is still - IMHO - closest thing to that ideal I have seen. To qualify that (before I get email from all my friends that happen to be Linux/BSD/Solaris fanatics enthusiasts: I agree that there are better, faster, safer versions of Unix available - OpenBSD, some Linux distros, etc etc. But using Mac is actually fun and pleasant experience, despite of all shortcomings and you can do with it much more than develop in Java or recompile C programs :-). For example run Photoshop or Textmate - none of which works under Linux.\nTherefore - Shane - do not hesitate to get a Mac. If my disk crash story made you reconsider, I am really sorry about that. Coffee sometimes ? Email me.\n","date":"June 30, 2008","externalUrl":null,"permalink":"/posts/2008-06-30-on-positives-of-negative-experience/","section":"Posts","summary":"A comment got to me via friend mentioning why am I suddenly so negative about Apple and Macs, which quite surprised me. True, I have had some serious hardware issues in first two weeks of June, but this negative event was about as much positive experience as hard disk crash can be.\nThinking back what I have learned and discovered from this:\n- Time Machine actually works\n- it pays to plug in the firewire disk with Time Machine backups every day - the two second operation saves a lot of time in long run\n- Carbon Copy Cloner is fantastic tool that makes creating bootable copy of your system disk as easy as possible\n- I can easily use multiple bootable disks with various versions of OS-X, not only for backing up but also for trying out new things / installs - a kind of \"VM on a disk\"\n","title":"On positives of negative experience","type":"post"},{"content":"\n","date":"June 15, 2008","externalUrl":null,"permalink":"/posts/2008-06-15-no-words-necessary-no-drm-either/","section":"Posts","summary":"\n","title":"No words necessary. No DRM either ...","type":"post"},{"content":"So, after few days working diskless, I am back to normal operation mode. About time, we are late with last episode of screencast ...\nThe copying of external disk went error free and took almost 5 hours (210 GB). Fortunately, the MBP was usable - I did not want to modify too many files, but it was perfect for Web research and writing in Google Docs.\nAfter reboot, the TimeMachine decided that 85 GB needs to be backed up again. This seems like bug in TimeMachine, because I have not really changed much more than few gigs - 4-5 max during the few days.\nSpotlight is also quite busy and completely confused - saying that I need to wait over minus two billion hours until it is done with indexing. That's pretty long - or pretty fast, depending how you see it :-)\n","date":"June 12, 2008","externalUrl":null,"permalink":"/posts/2008-06-12-back-to-normal/","section":"Posts","summary":"So, after few days working diskless, I am back to normal operation mode. About time, we are late with last episode of screencast ...\nThe copying of external disk went error free and took almost 5 hours (210 GB). Fortunately, the MBP was usable - I did not want to modify too many files, but it was perfect for Web research and writing in Google Docs.\nAfter reboot, the TimeMachine decided that 85 GB needs to be backed up again. This seems like bug in TimeMachine, because I have not really changed much more than few gigs - 4-5 max during the few days.\n","title":"Back to normal","type":"post"},{"content":"So, I have positive proof that the file system crash of last week was not a software problem in Leopard, but indeed caused by hardware failure. After restoring system from Time Machine, things looked pretty good - everything seemed to work. I was able to re-render the screencasts I have lost - I mean I have lost converted AVI files and MP4 files, not the \"source\" MOV files. I worked on Mac over Saturday and Sunday. Because my Time machine does not backup virtual machine images, I had even whopping 65 GB of free space :-). I saw a bit more of beachballs, but I thought (wishful thinking) it is because Spotlight is busy rebuilding index ...\nIn some moment of bliss I have asked my son to get and build for me 250 GB external FireWire disk with this beautiful enclosure and on Sunday evening, I tried for the first time wonderful program Carbon Copy Cloner that duplicated the harddrive to external one, promising bootability.\nOn Monday morning, at customer location I tried to copy VMWare image from network. System froze with beachball and had to be powered off. Same result for the second and third attempt ... with only difference that it did not boot back and hard disk started to make that weird clicking sound.\nI brought it to Apple service center which confirmed the problem, took out the disk, ordered replacement part and asked me to come back tomorrow. That would cause a problem, as I am attending few meetings in Montreal in next 2 days and need my notebook with me and in working condition.\nFortunately, the bootable external drive trick worked perfectly. After power on, I need to hold Option key and select the external disk - and everything works just fine. I am actually typing this on my Macbook Pro :-). No observable difference in speed, the only annoyance is that I cannot really use notebook in train or anywhere where there is no power supply for the drive.\nI am still amazed how flexible is the Mac hardware and how capable is the firmware. Being many years Windows user, before this, an idea of cloning disks and booting notebook from external hard disk seemed pretty far fetched. As they say in Germany - man lernt nie aus ....\n","date":"June 9, 2008","externalUrl":null,"permalink":"/posts/2008-06-09-diskless-macbook-pro/","section":"Posts","summary":"So, I have positive proof that the file system crash of last week was not a software problem in Leopard, but indeed caused by hardware failure. After restoring system from Time Machine, things looked pretty good - everything seemed to work. I was able to re-render the screencasts I have lost - I mean I have lost converted AVI files and MP4 files, not the \"source\" MOV files. I worked on Mac over Saturday and Sunday. Because my Time machine does not backup virtual machine images, I had even whopping 65 GB of free space :-). I saw a bit more of beachballs, but I thought (wishful thinking) it is because Spotlight is busy rebuilding index ...\n","title":"Diskless Macbook Pro","type":"post"},{"content":"It happened on Wednesday afternoon. I knew something is wrong with my MacBook Pro immediately - when I saw semi-dark screen, unresponsive machine - even mouse cursor was frozen - and heard fans blowing full speed, making the strange, clicking noise coming from inside almost disappear ...\nOS-X does not freeze too often, but it can happen and as a matter of fact, I have seen it happen before during my almost two years with Mac, so I did not panic. As expected, the Alt-Option trick did not work, so all I could do was to force power off.\nBut then, after reboot and \"bang\" sound, neither the rotating circle nor the blue screen showed up. I mean the good blue screen, background color of booting OS-X, not THAT blue screen, of course. Instead, screen stayed grayish and showing No-Entry sign ... And again and again ...\nAt first I was pretty sure that the hard disk is gone. But after booting up from install DVD (hold C during boot) and running Disk Utilities \"verify\" and \"repair\" disk, it did not find anything wrong with it. It was - according to Disk Utility - perfectly good, healthy disk, which only boot stubbornly returned to the No-Entry sign with each and every boot attempt. It was obvious that I will soon have an opportunity to really test out the Time Machine restore capabilities.\nNormally, I plug in the Time Machine backup disk every day after unpacking the notebook at home in my home office - and the magic of Leopard takes care of the rest. As Murphy wanted it, I had been working around the house and in the garden in last few days' evenings, rather than in my home office where the backup disk is. So it happened that last time I had plugged the disk in was around Saturday night and all changes afterwards were not backed up. Bummer.\nThe system did not allow Archive and Install option (which copies user data away before install) - it was too little space left, so only option was erase the disk and loose last few days worth of data and changes. Most of the chnages was either stored elsewhere as well (Gmail attachmanents) or at least redoable (some rendered screencasts), but last day work was nowhere else :-(\nThe good fellas at Carbon Computing (my nearest certified Apple service centre) made me aware of the FireWire mode: you press T during boot and Mac makes the hard disk available as external FireWire device, which can be attached to another Mac and read from it as from any external disk. This feature is supported by firmware and does not need any system installed. I tried it and it indeed worked, but the damage to the file system must have been fairly large, because I could not navigate deeper into the home directory.\nAfter I accepted that one and half day of work is lost, the reinstallation of the OS-X from scratch was very smooth and very fast experience - it took about 35 minutes. After booting up, system offered restore from TimeMachine and after another two hours, almost 180 GB of stuff was back on Macbooks harddrive. My Mac was almost exactly like on last Sunday morning .. The \"almost\" means that Time Machine does not quite restore every bit and piece because after system update check, Mac downloaded about 1 GB worth of patches from Apple side and required restart after install. The size of the patch indicates that it were most likely roll-ups of the updates from 10.5.0 t 10.5.3 - certainly more that could be missing in last few days - which would mean that TimeMachine does not really backup system files. I also had to re-enable root access and modify my /etc/hosts file to enter symbolic names for the VM's.\nBecause I have left out the podcast from the backups, it was pretty annoying to get my iTunes subscription back to normal: the downloaded but not yet listened to podcasts all had exclamation marks, because the iTunes library file was referring to non-existent files, but - because they were in the list, it did not re-download them. I had to delete podcast, resubscribe and re-download the episodes. Oh, well ...\nI am now back up and running and without any lost files other than those who were lost because of my laziness to plug in the disk. I think I start to see selling point for Time Capsule :-). Time machine is still working and I was listening to loud fans for quite couple of hours while Spotlight indexed all restored content again.\nI still do not know what caused the crash: I was doing lots of video re-encoding, so maybe overheating together with very little free space (I was twice close to 99.5% full disk). And maybe there is really something wrong with the disk.\nI have read somewhere that people that went through the near-death experience often change their priorities and behaviour. This certainly true with me after this cold shower. My trust to hard disks (in general) is even lower than before - and in panic, I have already caught up with delayed backups of the home server to two separate external hard disks. I will be also setting up bootable copy of the Mac disk (using CCC) as soon as Yan builds for me 250 GB external FireWire disk - I do not want risk that the disk will die again .. And in the meantime, my plugging discipline will certainly be flawless ;-)\nI have chatted about this with a friend and he asked whether I do not consider returning back to Windows, now when Mac disappointed me so badly and did let me down ...\nWell - combination of OS-X and Apple hardware is pretty solid combination, but certainly not as rock-solid as Apple marketing would like to make the world believe. I have just experienced a real-life proof that it can crash pretty badly. But I still believe that it is by far the best available option currently available. For variety of reasons.\nFirst of all, the most troubles I had, was caused by me not having good enough backup system. Every system is only as good as the weakest link, which is in most cases the human part of the workflow. If I would have used Time Capsule or at least plugged the disk every day, there would be no loss of data, just about 3-4 hours wait until being operable again. Which is much less than I have spent any time while rebuilding Windows machine. With Windows it took me 2-3 hours to install XP - with all three hundred twenty seven updates, thirteen reboots and lots of surfing to find latest drivers for all devices from vendor's sites. And then usually at least one full day to reinstall development environments, java, Visual studio, Office, tools etc from scratch.\nSecondly, I never had really good backups while working on Windows - mostly because doing backups was never as easy as connecting a hard disk. As result, I had much larger gaps between backups as nowadays. And considering how much work it was to selectively restore the data ... To sum it up: if this would happen on Windows machine, I would probably loose week or more of data not 1.5 days and to be back operational would take at least 1-2 days, not few hours.\nAnd third - while the OS-X was being installed, I was working on my old, beaten Fujitsu LifeBook - and I realized I how much I actually I miss the tools and overall user experience of the Macbook Pro.\nOn the positive side: now I know from the firsthand experience that Time Machine works (including restore) and I have learned couple of new neat features of Leopard. I never completely realized the possibilities of booting and running system from non-local disks. And I have now very good incentive to fix the broken automatic backups to Amazon S3 - at least as plan B until I buy Time Capsule ...\n","date":"June 6, 2008","externalUrl":null,"permalink":"/posts/2008-06-06-os-x-near-death-experience/","section":"Posts","summary":"It happened on Wednesday afternoon. I knew something is wrong with my MacBook Pro immediately - when I saw semi-dark screen, unresponsive machine - even mouse cursor was frozen - and heard fans blowing full speed, making the strange, clicking noise coming from inside almost disappear ...\nOS-X does not freeze too often, but it can happen and as a matter of fact, I have seen it happen before during my almost two years with Mac, so I did not panic. As expected, the Alt-Option trick did not work, so all I could do was to force power off.\n","title":"OS-X near-death experience","type":"post"},{"content":"I have got a letter from Online Rights Canada. I believe that what is about to hapen, may have pretty deep implications down the stream. Minimum thing I can do is try to help spreading the word.\nHere is the message:\nDear Online Rights Canada Supporter,\nWe understand that the government will imminently introduce legislation to amend the Copyright Act - and it intends to push it through quickly. We at Online Rights Canada wanted to let you know what was ahead in the next few weeks, and what you can do to protect Canada from a new DMCA.\nWhen we do get a copyright bill, we need a period to study the bill, and we need thorough Committee hearings that offer a wide range of stakeholders the opportunity to present their views to the Canadian government. We need to challenge Parliament to give provide oversight. If the current government tries to rush this bill through the Summer, we need to stop it in its tracks.\nAll the signs suggest that the bill will be a Canadian version of the American DMCA with a veneer of consumer concessions. The bill will likely include laws modeled on the DMCA instead of the approach adopted by earlier Canadian proposals. Concessions may include a time-shifting right and a format-shifting right, legalizing consumer use of the VCR and iPod after all these years. However, by protecting DRM at the same time, the government kills those consumer rights anywhere the content is locked down!\nWhat can you do? Advocacy! Contact your MP - use the advocacy tools at http://www.CopyrightforCanadians.ca and the Facebook group, Fair Copyright for Canadians http://www.faircopyrightforcanada.ca/ to make sure Ottawa knows your views.\nAnd get others to do so, as well - we'll need a summer full of copyright activism to make sure that Ottawa knows that Canada's copyright laws have to put Canadians' interests first!\nTo start, take two minutes to send our first letter to MPs about the impending bill. Just visit:\nhttp://www.onlinerights.ca/get_active/copyright_for_canadians/\nand start spreading the word to your Member of Parliament!\nThanks again,\nOnline Rights Canada\n","date":"June 2, 2008","externalUrl":null,"permalink":"/posts/2008-06-02-dmca-for-canada-act-now/","section":"Posts","summary":"I have got a letter from Online Rights Canada. I believe that what is about to hapen, may have pretty deep implications down the stream. Minimum thing I can do is try to help spreading the word.\nHere is the message:\nDear Online Rights Canada Supporter,\nWe understand that the government will imminently introduce legislation to amend the Copyright Act - and it intends to push it through quickly. We at Online Rights Canada wanted to let you know what was ahead in the next few weeks, and what you can do to protect Canada from a new DMCA.\n","title":"DMCA for Canada ? Act now !","type":"post"},{"content":"I had this discussion with a friend where we both found out that there is surprising amount of very useful little apps and tools in Mac's software world that people use on daily basis and which are worth of spreading word about. Here is first of the programs I did not know about few months ago - and today I barely can imagine working without them.\nVisualHUB is simple but very powerful video convertor for Mac. It is simple in the user interface:\nAll you have to do is to drag and drop source files into the file area and select the target format and parameters. Then press Start and wait - surprinsingly short time. VisualHUB is very fast - the duration depends on the source format and the destination but (unlike with iMovie) it does not take hours to render 20 minutes movie ...\nIt supports all usual formats - MOV, MP4, MPEG as well as AVI and what I find very useful is suport for PSP. The VisualHUB is the easiest and most reliable way I have tried so far to transfer the DVD movie to the PSP - for the kids to watch in the car.\nWhat we use it for to transform the source files for screencast generated by CamStudio on Windows (AVI) into the format that can be loaded into the iMovie (which happens to be MP4 with H264) so that clarity of screen is retained. We also use it to produce AVI version of the screencast playable on Windows Media Players - for the Windows users stubborn enough to resist installation of Quicktime or free players such as VLC. Before this, I have tried few other options, none of which really worked. VisualHUB does pretty good job at compression - the 420 MB MOV file got compressed into under 100 MB file AVI (with very acceptable loss of quality). The result of exporting the same MOV file into AVI with Quicktime Pro produced over 600 MB that was visually worse than the VisualHUB AVI output.\nI am not an expert in video formats and video conversions (therefore it is quite possible that I could have done it better with some more digging with QT Pro) - and I do not plan to become one. Which is why the VisualHub is such a great tool for my needs.\nHighly recommended - and thanks to Gabo who introduced me to this little gem.\nDisclaimer: I am not affiliated or anyhow interested in sales or marketing of this product. The only reason I am recommending it is because I like it and find it useful.\n","date":"June 1, 2008","externalUrl":null,"permalink":"/posts/2008-06-01-mac-gems-visualhub/","section":"Posts","summary":"I had this discussion with a friend where we both found out that there is surprising amount of very useful little apps and tools in Mac's software world that people use on daily basis and which are worth of spreading word about. Here is first of the programs I did not know about few months ago - and today I barely can imagine working without them.\nVisualHUB is simple but very powerful video convertor for Mac. It is simple in the user interface:\n","title":"Mac Gems: VisualHub","type":"post"},{"content":"I've been writing a lot of code for the past 6 months. I have to admit, it is a welcome change from Word documents and PowerPoint presentations. Java, unlike text and graphics has a clearer definition of correct and finished.\nFrom Software Is A Craft by Dan Pritchett\n","date":"May 21, 2008","externalUrl":null,"permalink":"/posts/2008-05-21-quote-of-the-day-13/","section":"Posts","summary":"I've been writing a lot of code for the past 6 months. I have to admit, it is a welcome change from Word documents and PowerPoint presentations. Java, unlike text and graphics has a clearer definition of correct and finished.\nFrom Software Is A Craft by Dan Pritchett\n","title":"Quote of the day","type":"post"},{"content":"I had the pleasure to listen very interesting podcast where Scott Hanselman and Quetzal Bradley discussed unit testing named \"Testing after Unit Tests\". To increase the Google Karma of the information discussed I have decided to rehash and sum up few main ideas of this discussion.\nQuetzal introduced the idea of \"negative coverage\" - meaning that if you have 88 % test coverage, you should not see this as something positive you have achieved, but as something missing (you miss 12 % of completion) - thus the title of this post.\nHe also offered very nice mental model of unit tests: see all possible paths through your code as network of roads in a state. Your unit tests are like taking small car and start driving through these roads. If you go through 88% of the roads, you can at least tell that all these roads and bridges are finished and passable with the small car driving at normal speed, that there are no fallen trees on the road and so on.\nYou cannot say anything about the remaining 12 % roads and bridges you have not visited. They may not exist at all - or be only half finished. You simply do not know.\nIt is also important to understand that you do not now how many those 88% tested roads will still be OK when you try to drive through with a 18 wheeler truck - or at 250 km/h in a sports car (feel free to fill in your favorite racing car make ...).\nThe parallel goes even further in matching the \"freeways\" and side roads with main execution paths vs sideroads (you have to take freeway in order to get to the sideroad) - but to get all, get a podcast, load it to your iPod (or Zune ;-)) to find out more.\nI keep listening to Hanselminutes because I like the content and the style and also to keep a tie to Microsoft world during the periods I am working outside of .NET (like in last 10 months). But even if you are not developing in Microsoft environment, many episodes of Hanselminutes very often bring ideas with much wider applicability. This is one of them.\nRecommended.\n","date":"May 19, 2008","externalUrl":null,"permalink":"/posts/2008-05-19-unit-testing-debt/","section":"Posts","summary":"I had the pleasure to listen very interesting podcast where Scott Hanselman and Quetzal Bradley discussed unit testing named \"Testing after Unit Tests\". To increase the Google Karma of the information discussed I have decided to rehash and sum up few main ideas of this discussion.\nQuetzal introduced the idea of \"negative coverage\" - meaning that if you have 88 % test coverage, you should not see this as something positive you have achieved, but as something missing (you miss 12 % of completion) - thus the title of this post.\n","title":"Unit testing debt","type":"post"},{"content":"Today I tried for the first time the iDVD 08 with intention to create DVD version of the screencast - just to find out that the application dies right after the start. From the error report (thanks for that) the problem was in missing dependency Oxygene framework - a module similar to Windows DLL. Here is the error message:\n[sourcecode language='xml']\nLink (dyld) error:\nLibrary not loaded: @executable_path/../Frameworks/Oxygene.framework/Versions/A/Oxygene\nReferenced from: /Applications/iDVD.app/Contents/MacOS/iDVD\nReason: image not found\n[/sourcecode]\nThe solutions described in the Apple discussion groups revolved around using shareware tool Pacifist - something I did not like particularly. The plain reinstallation of the DVD did not help either.\nWhat worked for me and solved the problem was complete removal of iDVD and subsequential reinstall. I used AppZapper to remove the application, but it also can be done manually by deleting the application bundle from /Applications, removing all iDVD receipts from /Library/Receipts and all content from ~/Library/iDVD and ~/Library/Preferences (which is in a nutshell all AppZapper did).\nRight after removal, insert Installation disk 1, select Install Bundled Software Only, press Customize and uncheck everything except iDVD. The program starts fine after installation finishes.\nOne more minor hickup after reinstall was that the Theme introduction would not play in preview - all the application showed was black screen with background music. This was resolved by selecting 'Check for updates' and allowing installation of the update. Afterwards, I was able to start working in my first DVD :-).\n","date":"May 15, 2008","externalUrl":null,"permalink":"/posts/2008-05-15-fix-for-idvd-08-crash-after-the-start/","section":"Posts","summary":"Today I tried for the first time the iDVD 08 with intention to create DVD version of the screencast - just to find out that the application dies right after the start. From the error report (thanks for that) the problem was in missing dependency Oxygene framework - a module similar to Windows DLL. Here is the error message:\n[sourcecode language='xml']\nLink (dyld) error:\nLibrary not loaded: @executable_path/../Frameworks/Oxygene.framework/Versions/A/Oxygene\nReferenced from: /Applications/iDVD.app/Contents/MacOS/iDVD\nReason: image not found\n","title":"Fix for iDVD 08 crash after the start","type":"post"},{"content":"As if the yesterday's Firmware update issue was not enough, I had very strange experience with iMovie 08. Suddenly, for no obvious particular reason the user interface became very unresponsive, I was not able to select project in project library. Switching Event library and Project windows on or off stopped working. Windows were not redrawn properly. Creating new project had no visible effect. I could not click on project to select it (well, technically I *could* click, but nothing happened). The time sliders in Events and Projects were either disabled or invisible ...\nHere is how the iMovie looked like most of the time:\nI tried multiple things to fix that: Logout and re-login - no change. Reboot (remember, I came from Windows where this very often used remedy ;-)). No luck. Check and repair the permissions using Disk Utility. No improvement. Verify disk. No errors and still no improvements.\nI even resorted to reinstallation of iLife 08. The only effect I achieved was that I got back trial version of Office 2004 which I deleted right after installing Leopard and had to download and install several updates for Garage Band and iWeb - but iMovie still did not work. Installation of iMovie HD (from iLife 06) worked OK as well did the iMovie 06 - but that was not much help because I did not want start from scratch and iMovie 08 with all its bad features is still able to accept way more input formats than '06.\nAfter killing well over three hours that was supposed to be spent on finishing the screencast, I started to delete all iMovie project files and even libraries from previous attempts. And suddenly, iMovie sprung to life and was as before.\nI think that reason for the issues was moving the Events library for some of the older screencasts to external disk, but leaving the Project files in iMovie. Somehow this must have confused the program and the non-responsiveness could be caused by trying to connect the thumbnails and file references from the projects to the not available source clips from event library.\nLesson learned: whenever I move done an event library used in the screencast to external hard disk, it is probably safest to backup and remove the project as well. In other words - keep these two words separated and disjunct.\nBut of course - this can also be a pure coincidence and everything can have completely different cause. Time will tell. Too bad that Premiere Elements does not exist for Mac platform. Maybe I should seriously consider looking at Final Cut Express ?\n","date":"May 13, 2008","externalUrl":null,"permalink":"/posts/2008-05-13-imovie-08-and-mystery-of-disappearing-project-library/","section":"Posts","summary":"As if the yesterday's Firmware update issue was not enough, I had very strange experience with iMovie 08. Suddenly, for no obvious particular reason the user interface became very unresponsive, I was not able to select project in project library. Switching Event library and Project windows on or off stopped working. Windows were not redrawn properly. Creating new project had no visible effect. I could not click on project to select it (well, technically I *could* click, but nothing happened). The time sliders in Events and Projects were either disabled or invisible ...\n","title":"iMovie 08 and mystery of disappearing Project Library","type":"post"},{"content":"Today I (finally) found out that Apple pushed the long expected Java update with Java 6 for OS-X. Together with this update was another one - Firmware update. I installed both, but on next login, the same firmware update showed up again and checking the firmware version with System Profiler has shown that it was not updated.\nSo I installed firmware update again, and rebooted. But nothing happened again.\nAfter some googling, I found out that the Firmware update - unlike all other updates does NOT really install itself. What it does is to download the Firmware update program. After you start this program (you can locate it by Spotlight), it will display instructions and asks for initiating shutdown. When machine reboots, you need to press and hold power button while it boots - until hearing long beep sound or seeing the sleep light rapidly flashing. After this, system shows update progress bar under grey apple and on finishing the update reboots again. Having done this, firmware is finally updated.\nFrom technical point of view it makes lots of sense to perform firmware update this way, but it would be very helpful if Apple would at least TELL the users what they are supposed to do. This was so un-applish user interaction experience like none before ...\n","date":"May 12, 2008","externalUrl":null,"permalink":"/posts/2008-05-12-mac-firmware-update/","section":"Posts","summary":"Today I (finally) found out that Apple pushed the long expected Java update with Java 6 for OS-X. Together with this update was another one - Firmware update. I installed both, but on next login, the same firmware update showed up again and checking the firmware version with System Profiler has shown that it was not updated.\nSo I installed firmware update again, and rebooted. But nothing happened again.\nAfter some googling, I found out that the Firmware update - unlike all other updates does NOT really install itself. What it does is to download the Firmware update program. After you start this program (you can locate it by Spotlight), it will display instructions and asks for initiating shutdown. When machine reboots, you need to press and hold power button while it boots - until hearing long beep sound or seeing the sleep light rapidly flashing. After this, system shows update progress bar under grey apple and on finishing the update reboots again. Having done this, firmware is finally updated.\n","title":"Mac firmware update","type":"post"},{"content":"Thanks to great weather, the walking season is in full progress :-) and that means I was able to add some more listening material to my podcast collection. I still keep track with all part of TWIT network - This week in tech, Security Now!, MacBreak Weekly and Windows Weekly - but that is nowhere close enough for both walking and driving ...\nI have returned back to listening to Scott Hanselman blog (Hanselminutes) - mostly out of curiosity how did working for Microsoft change is very balanced and realistic view of technologies.\nFortunately - it did not.\nScott is still same great, very open minded developer that can see value and strength as well as issues and problems in technology regardless of its origin. It speaks a lot positives about Microsoft as well - by allowing this to happen.\nVery good episodes are (back from 2007) from my personal point of view were:\nEclipse with Bjorn Freeman-Benson Software Architecture with Dan Appleman 2007 The Year in Review What's it like for Mac Developers - Interview with Steven Frank of Panic I was pretty intrigued with the title of the episode \"The Worst Show Ever with Chris Sells and Rory Blyth\" - which is Episode 112 and I have to agree, the title was pretty descriptive :-) - but it was at least reasonably funny.\nI am looking forward catching up with rest of the year, which according the Weather Network should not take too long.\nThanks, Scott. Keep up the great content coming.\n","date":"May 8, 2008","externalUrl":null,"permalink":"/posts/2008-05-08-catching-up-with-hanselminutes/","section":"Posts","summary":"Thanks to great weather, the walking season is in full progress :-) and that means I was able to add some more listening material to my podcast collection. I still keep track with all part of TWIT network - This week in tech, Security Now!, MacBreak Weekly and Windows Weekly - but that is nowhere close enough for both walking and driving ...\nI have returned back to listening to Scott Hanselman blog (Hanselminutes) - mostly out of curiosity how did working for Microsoft change is very balanced and realistic view of technologies.\n","title":"Catching up with Hanselminutes","type":"post"},{"content":"as long as you are Safari Books online subscriber - see it here.\nCompletely updated with XCode 3.x and Objective C 2.0. The screenshots even show the iPhone project templates, indicating the XCode 3.1 in some places. So far the only difference against reality I have found is not covering the XIB resource format (which is generated by default) and sticking with NIB. This blog entry has good explanation of the difference.\nIf you are fan of dead tree-ware books, the official publication date is May 2008, so expect it any day :-).\nStrangely enough, as of May 4th, the author's web (The Big Nerd Ranch) does not really advertise its availability (yet)\n","date":"May 4, 2008","externalUrl":null,"permalink":"/posts/2008-05-04-cocoa-programming-for-mac-os-x-third-edition-is-out/","section":"Posts","summary":"as long as you are Safari Books online subscriber - see it here.\nCompletely updated with XCode 3.x and Objective C 2.0. The screenshots even show the iPhone project templates, indicating the XCode 3.1 in some places. So far the only difference against reality I have found is not covering the XIB resource format (which is generated by default) and sticking with NIB. This blog entry has good explanation of the difference.\n","title":"Cocoa Programming for Mac OS X, Third Edition is out","type":"post"},{"content":"I do not blog on political issues, but this one is kind of different.\nCouple of weeks ago I received a letter from my ISP provider (Rogers Cable), stating that days of unlimited downloads are over. More or less. Rogers capped the monthly transfer depending on your subscription plan, which in my case means maximum 95 GB / month for sum of upload and download.\nThey started to monitor the traffic in December and will start charging for the transfer exceeding the cap in June.\nAfter overcoming feelings of being cheated (after all, I signed up for \"unlimited\" service and that !@#$ ISP did change the level of the service unilaterally) and discovering there is probably no real alternative (I could not find reasonably priced ISP that would not be reselling Bell ADSL service), I started to think about what does this actually mean and what are the consequences.\nIf you have limited capacity resource (like bandwidth) and potentially unlimited demand, some measures must be taken. In ideal world - when the number of subscribers is optimal with respect to capacity and their behaviour is not trying to consume as much bandwidth as humanly possible - you may get by without restrictions.\nIn real world where some people are downloading movies in hundreds of gigabytes, this approach does not work quite so good. Limiting consumption of the bandwidth is the solution most providers end up implementing.\nThis can be done two way: transfer cap and traffic shaping. In transfer cap, ISP measures the total volume transfered. In traffic shaping the ISP goes after protocols that usually related with really high volumes and try to throttle them. Usual victim is Bittorrent, which is quite often used to download illegal copyrighted content in form of movies and music, as well as other Peer-To-Peer protocols used in file sharing.\nIt is not easy to choose between these two bad (from consumer standpoint) solutions to congestion problem. I am no way a Rogers fanboy (despite of - or because of - being their customer for almost 10 years), but I think that their solution is better one.\nI do not download movies or MP3 from torrent sites, but I have two large issues with traffic shaping approach. First, who decides which traffic is being throttled and how ? Torrent is preferred way how to distribute large binary images of Linux distributions or VMWare appliances, and targeting torrents significantly affects the open source communities, which cannot pay for data bandwidth and host the downloads on sites like Amazon S3. These projects are put into same category like PirateBay just because they use same protocol - so this approach is violation of the presumption of innocence.\nTo make absurdity of the approach more obvious, this is same logic as if somebody would start dropping HTTP just because there are sites on the net that are providing illegal or dangerous content: viruses, exploits, pornography ... For the argument that (unlike in HTTP case) most of torrent traffic is illegal (which is an assumption, because nobody has really good data), let's have a look at email: assumably around 90% of all email traffic is spam. Why not fight the bad guys by crippling SMTP/POP3 traffic, if we use same logic ?\nMy second issue is that, once the traffic shaping is acceptable business practice, who guarantees that only reason for throttling is to (assumably) limit possibly illegal content and not e.g. hurt the service of competition providing e.g. VOIP services ?\nRecently the whole issue of traffic shaping got lot of attention in Canada - read the excellent blog of Michael Geist. There are even plans to organize a Net Neutrality rally on Parlament Hill - see the http://netneutralityrally.ca/ - so if you are in Ottawa on given date, give it a thought.\nSo however I hate Roger's cap, I have to agree that this time, they approached the problem correctly. Only two concerns: with more and more services moving online, the 95GB is definitely not enough. I am subscriber of MSDN/Technet as well as Apple Developer's Connection and with updates, patches etc I can easily need 40-50 GB a month just for the downloads they provide. Also more and more audio and video is delivered online - I just checked the size of Movies folder in iTunes, containing only video's of Apple developers series and few selected videocasts and it has well over 120 GB. Add using YouTube, Lynda.com, Safari books online and similar and the final number will be well above. Unless the monthly allowance will increase, we will run out pretty soon.\nSecond concerns is about reliability of the traffic data. I am not measuring my internet traffic, but quite often I think there may be pretty large gap between what I was doing online and what daily meter (available from Roger's website) reports.\nI think that what we in Canada really need is more competition in the telecom and ISP area. The comparison of what Canadians can get for their money to USA in data and wireless plans looks pretty depressing - and do not even try to compare with Scandinavia or some Asian countries. Unless there is real alternative to Rogers (other than Bell), there will be hardly any pressure on prices and services offered. Maybe we should think about opening the regulation of the telecom market and allowing more foreign competition during next election campaign ?\nOh, one more thing: Steve Gibson of Security Now! fame did excellent coverage of the issues network capacity and network congestion. I highly recommend to listen to this episode if you haven't done so.\n","date":"May 3, 2008","externalUrl":null,"permalink":"/posts/2008-05-03-rogers-bell-and-net-neutrality/","section":"Posts","summary":"I do not blog on political issues, but this one is kind of different.\nCouple of weeks ago I received a letter from my ISP provider (Rogers Cable), stating that days of unlimited downloads are over. More or less. Rogers capped the monthly transfer depending on your subscription plan, which in my case means maximum 95 GB / month for sum of upload and download.\nThey started to monitor the traffic in December and will start charging for the transfer exceeding the cap in June.\n","title":"Rogers, Bell and Net neutrality","type":"post"},{"content":"What does really big mean ? In my case few hundred megabytes, up to 1 GB. Clearly, too much for email attachments - most providers caps them at around 5-15 MB.\nSince we started doing screencasts, I need quite often to transfer work in progress - screen recordings, rendered MOV files between me and my co-host of the screencasts. I tried to upload the file to the company servers using VPN, but the speed of the secure uploads is nowhere close to being practical.\nWhat works much better is free service called TransferBigFiles.com. There is no registration required, you just enter the recipient email and start upload. After uploading, the system sends you an email with link and the files stays up for few days, then is deleted. More than enough for the other party to download. With self-destruction, it is also less worries for you to remember clean-up.\nThe site also offers client for Windows, which I did not try (for obvious reasons) and shows ads selling software. These ads made me (strangely enough) more comfortable, as the intention of the creators is clear: attract traffic by free service and monetize on software sales / ads.\nThe other possible explanation is of course collecting of email adresses for not-so-noble purposes. I have no knowledge of this being the fact - since about a week and half of using the service, there was no spike in amount of spam. No spike meaning nothing beyond usual 300+ offers of 10 dollar Rolex, body enlargements, natural weight loss programs and help requests to transfer money from Nigeria and similars ...\nAll my emails are consolidated on Gmail, which does terrific job of weeding out 99.99% of these - so I do not really care so much if one more spammer gets my email. But if you are really worried, you can always get the 10 minute email, use it for receiving notifications and then email the link manually. The down side is that you must keep the 10 minute email alive until upload finishes - this may take few refreshes.\n","date":"April 29, 2008","externalUrl":null,"permalink":"/posts/2008-04-29-easy-way-how-to-transfer-really-big-files/","section":"Posts","summary":"What does really big mean ? In my case few hundred megabytes, up to 1 GB. Clearly, too much for email attachments - most providers caps them at around 5-15 MB.\nSince we started doing screencasts, I need quite often to transfer work in progress - screen recordings, rendered MOV files between me and my co-host of the screencasts. I tried to upload the file to the company servers using VPN, but the speed of the secure uploads is nowhere close to being practical.\n","title":"Easy way how to transfer really big files","type":"post"},{"content":"I am using OmniGraffle for most of my diagrams. OmniGraffle is an OS-X platform replacement for Visio - only easier to use and better looking (in my opinion). On rare occasions I do not work on my notebook, it is quite useful to have free alternative that allows to create a diagram that does not look too awful, without going through the hoops of downloading and installing software. The bubl.us is exactly that tool.\nUsing bubl.us you can very quickly create visual representation of simple structure with basic relations (parent/child) and links. You can define the text and links between elements and save the result as XML, HTML or JPG/PNG image. The result can look e.g. like this:\nNo a bad result, considering that its creation took less than 60 seconds.\nIf you need more control - like different shapes and stencils, look at Gliffy, which is much closer to actual desktop diagramming tool. It is free tool with paid enhanced version, available here.\n","date":"April 28, 2008","externalUrl":null,"permalink":"/posts/2008-04-28-quick-online-diagramming-tool/","section":"Posts","summary":"I am using OmniGraffle for most of my diagrams. OmniGraffle is an OS-X platform replacement for Visio - only easier to use and better looking (in my opinion). On rare occasions I do not work on my notebook, it is quite useful to have free alternative that allows to create a diagram that does not look too awful, without going through the hoops of downloading and installing software. The bubl.us is exactly that tool.\n","title":"Quick online diagramming tool","type":"post"},{"content":"Yesterday, I have noticed interesting thing related to Finder and \"beach ball of the death\". Suddenly, for no obvious reason, the top menu became unavailable and cursor changed to beachball every time I moved it there. The Bluetooth mouse stopped responding. Finder stopped responding. All symptoms as if Finder would hanging ...\nThe cause of the issue was crash of unrelated application (iShowU, if you are curious), which brought up the crash report window. For some reason - maybe because it happened while changing spaces - the window was not visible. After closing the window, everything came back to life and even mouse reconnected (after disabling and re-enabling Bluetooth).\nSo next time it looks like an application did hang, make first sure that no windows expecting input are not open and hidden. Do not rely upon jumping dock icon - with bad luck and Spaces enabled, it is easy to switch the notification off.\n","date":"April 24, 2008","externalUrl":null,"permalink":"/posts/2008-04-24-a-false-hang-of-finder/","section":"Posts","summary":"Yesterday, I have noticed interesting thing related to Finder and \"beach ball of the death\". Suddenly, for no obvious reason, the top menu became unavailable and cursor changed to beachball every time I moved it there. The Bluetooth mouse stopped responding. Finder stopped responding. All symptoms as if Finder would hanging ...\nThe cause of the issue was crash of unrelated application (iShowU, if you are curious), which brought up the crash report window. For some reason - maybe because it happened while changing spaces - the window was not visible. After closing the window, everything came back to life and even mouse reconnected (after disabling and re-enabling Bluetooth).\n","title":"A false \"hang\" of Finder","type":"post"},{"content":"Introducing code review and pair programming has often an impact on relationships in the team - especially when a critique needs to be delivered. It takes great degree of experience on both sides to communicate defects in the code for both the reviewer as well as for the code author to get something useful out of it.\nI found this at http://www.finetix.com/blogs/finetixblogs.html which can be helpful (page is 404-ing now, but I luckily saved it in Google Docs way back) :\nEveryone, including me, repeat after me:\nI am not my code. A criticism of my code doesn't have to be a personal attack on me. I am not the tools that I use.\nA criticism of my tools shouldn't be construed as a personal attack on me. I am not the programming language that I use I will try to remember it (and read it to all participants) next time we get into the passionate discussion about whether inheritance or delegation is the correct approach to implement feature X :-)\n","date":"April 21, 2008","externalUrl":null,"permalink":"/posts/2008-04-21-agile-development-team-member-mantra/","section":"Posts","summary":"Introducing code review and pair programming has often an impact on relationships in the team - especially when a critique needs to be delivered. It takes great degree of experience on both sides to communicate defects in the code for both the reviewer as well as for the code author to get something useful out of it.\nI found this at http://www.finetix.com/blogs/finetixblogs.html which can be helpful (page is 404-ing now, but I luckily saved it in Google Docs way back) :\n","title":"Agile development team member mantra","type":"post"},{"content":"Spam has always been a big problem for all blogs. Fortunately, worpress.com provides wonderfull Akismet spam filter which is works amazingly well. I do have switched on moderation for all comments, to make sure no spam gets through, but without Akismet it would be impossible to manage it because of the spam volume. Since I started this blog (August 2006), it caught over 17'000 (yes, seventeen thousands) spam posts. In other words, about 30 spam comments a day or almost 60 spam comments per published post.\nIn past few days I have notices new type of spam comments that pass through Akismet. What is really confusing, is that there is no obvious message in the text - no usual wonderdrugs, ten dollar Rolex or enlargement of body parts offers. Some of the links even point to quite legitimate, non commercial sites. I did not spend any time on it to find out a pattern yet. Some kind of campaign ? Few sites were related to stop animal cruelty - a very noble and worthy goal to support, but certainly not with methods like this ...\nAnybody else having similar experience ?\nHere is what it looks like (I am posting it as image to avoid promoting the spammer):\n","date":"April 20, 2008","externalUrl":null,"permalink":"/posts/2008-04-20-weird-kind-of-spam-that-passes-through-akismet/","section":"Posts","summary":"Spam has always been a big problem for all blogs. Fortunately, worpress.com provides wonderfull Akismet spam filter which is works amazingly well. I do have switched on moderation for all comments, to make sure no spam gets through, but without Akismet it would be impossible to manage it because of the spam volume. Since I started this blog (August 2006), it caught over 17'000 (yes, seventeen thousands) spam posts. In other words, about 30 spam comments a day or almost 60 spam comments per published post.\n","title":"Weird kind of spam that passes through Akismet","type":"post"},{"content":"","date":"April 17, 2008","externalUrl":null,"permalink":"/tags/event/","section":"Tags","summary":"","title":"Event","type":"tags"},{"content":"Last week I attended one day event organized by Microsoft named Heroes Happens Here. It is series of introduction targeting new products: Windows Server 2008 (not out yet) SQL Server 2008 (not out yet) and Visual Studio 2008 (out and well).\nI do not do much Microsoft development these days - my world is currently rather unevenly divided between Java (about 70 %), Web-ish technologies (XHTML, CSS, JavaScript, some Ruby) and OS-X (Objective C) which I am trying to squeeze in and get finally started. But Microsoft is such important platform that one must pay attention what is going on.\nThe event was well prepared and well executed. After all, Microsoft is doing this for quite some time and experience shows. For the first time, there were more people attending that the space in Cineplex allowed - so there were overflow rooms with huge projection screen for the slides/demos and smaller screen showing the video-feed of the presenter. We ended up in overflow room. One very important comment to whoever was in charge of camera control: please do NOT zoom in on presenter and then try to follow him as he walks. Seeing how the space floats in front of your eyes is quite nauseating experience. Even if the speaker is good looking guy (as I overheard from some female attendants), most of the audience does not really care about detailed snapshot of his face with moving background, but about slides and his words. Think about the people in the other room - if they are fine with seeing the presenter from large distance, so are we. No need to play movie director and add \"dynamism\" to the stream.\nThe above is probably only objection to the format and execution of the event - all the rest was fine. The speakers were great (thanks, Christian) and the script was surprisingly well acted on. You guys have more talent than just technology evangelism.\nFrom the products introduced I was mostly interested in VS 2008 and SQL Server 2008. I really liked the enhancements done in 2008. Nothing revolutionary, but nice features that make coding experience and developer productivity so much better. I wish the VS 2005 had this features :-). However - and there is always however - I have seen nothing that Eclipse/IntelliJIDEA/Netbeans would not offer for quite some time. In many areas the VS is still playing catch-up (like refactoring), in others will probably never quite catch up (extensibility - being a closed source product not an open source platform). But now, it is closer than ever. Where VS will probably beat Eclipse is speed of execution and look \u0026amp;\u0026amp; feel (being a native App). I am looking forward to find out. Great work, Microsoft. It is important that there is more than one platform/toolset to keep the innovation going.\nI am also quite excited about enhancements in SQL server 2008, specially in BI area and reporting. I will wait for the release to find out though - no cycles right now. I just hope the features will not disappear the same way as the WinFS did from Vista.\nThe Windows Server 2008 is least important from my personal perspective. With more and more services moving into the cloud and progress in virtualization (\"software appliances\"), there are IMHO better alternatives to host your VM's on - as well as better OS-es to be used as guest OS. I would probably prefer to use some derivate of Unix for both (OS-X or Linux) or true VM Host (VMWare) and Unix combination. Buying Windows license to run appliance starts to be prohibitively expensive, if you want to build many of them.\nOne final remark to the general impression from this and past Microsoft tech events: I realize that tone of the announcement and presentation must be upbeat and optimistic, but there is no reason make it sound as if Microsoft just invented it and if that was the greatest innovation since the TCP/IP protocol. Even more if it is basically a bug fix feature: \" .. and now, the graphic designer of Web page actually works and does not rearrange and screw up your markup every time you switch into visual mode and back as in VS 20xx\".\nI was very happy to observe that this \"spirit\" was tuned down a lot. What I have seen on this year HHH is more sober, mature Microsoft that has really competitive product and does not need to sink down to the FUD as often as before - they even mentioned \"works with Firefox\" ;-), but still did not dare to say the G word.\nOn the other hand - what kind of \"innovation\" is to say that you do not really need to run GUI on Web server ? Did the last 30 years not happen or what ? Just because until PowerShell came out, the Windows \"shell\" was such a lame and hardly usable tool for doing anything non-trivial (compared to e.g. BASH), it does not make making GUI mandatory a good idea. And allowing GUI-less server should be more appropriately presented as \"OK, we were wrong but we fixed it\" rather than \"Look what cool feature we have just added\".\nAs Henry Spencer once said:\n\"Those who do not understand Unix are condemned to reinvent it. Poorly\"\n","date":"April 17, 2008","externalUrl":null,"permalink":"/posts/2008-04-17-heroes-happened-here/","section":"Posts","summary":"Last week I attended one day event organized by Microsoft named Heroes Happens Here. It is series of introduction targeting new products: Windows Server 2008 (not out yet) SQL Server 2008 (not out yet) and Visual Studio 2008 (out and well).\nI do not do much Microsoft development these days - my world is currently rather unevenly divided between Java (about 70 %), Web-ish technologies (XHTML, CSS, JavaScript, some Ruby) and OS-X (Objective C) which I am trying to squeeze in and get finally started. But Microsoft is such important platform that one must pay attention what is going on.\n","title":"Heroes Happened ... here","type":"post"},{"content":"","date":"April 17, 2008","externalUrl":null,"permalink":"/tags/microsoft/","section":"Tags","summary":"","title":"Microsoft","type":"tags"},{"content":"It happened few days ago for the first time: after opening the lid on my MacBook Pro, the machine woke up, but the screen stayed dark. Whatever I did, I just could see cursor and nothing underneath. I had to resort to unthinkable - reboot :-(\nSome research showed this is known problem - which is from certain point of view good, because many people found hopefully many workarounds. The more information can be found here, here and here. Very helpfull was also this page.\nThere are speculations about some software that may be related to the problem. As matter of fact, I have installed after some time of not using it one of the suspects: iStat Pro dashboard widget.\nWhat I have done to minimize chances of reoccurence:\n- removed the iStat Pro and Polar Clock screen saver (which was also new install)\n- switched off the setting 'Automatically reduce the brightness of the display before sleep'\n- started to switch off the bluetooth mouse before closing the lid (so that BT is off when sleeping)\nI have also switched off the \"safe sleep\" mode which is not of much use as my notebook never stays unopened for longer that 12 hours :-).\nSo far, everything works OK. Let's keep the fingers' crossed ...\n","date":"April 16, 2008","externalUrl":null,"permalink":"/posts/2008-04-16-the-dark-screen-club/","section":"Posts","summary":"It happened few days ago for the first time: after opening the lid on my MacBook Pro, the machine woke up, but the screen stayed dark. Whatever I did, I just could see cursor and nothing underneath. I had to resort to unthinkable - reboot :-(\nSome research showed this is known problem - which is from certain point of view good, because many people found hopefully many workarounds. The more information can be found here, here and here. Very helpfull was also this page.\n","title":"The dark screen club","type":"post"},{"content":"Program managers want an infinite number of features in zero time, testers and service operations staff want zero features over infinite time, and developers just want to be left alone to code cool stuff.\nFrom I. M. Wright's \"Hard Code\"\nby Eric Brechner\n","date":"April 9, 2008","externalUrl":null,"permalink":"/posts/2008-04-09-quote-of-the-day-12/","section":"Posts","summary":"Program managers want an infinite number of features in zero time, testers and service operations staff want zero features over infinite time, and developers just want to be left alone to code cool stuff.\nFrom I. M. Wright's \"Hard Code\"\nby Eric Brechner\n","title":"Quote of the day","type":"post"},{"content":"There is a saying that necessity is the mother of invention. Such necessity happened last week and forced me to try out the Groovy language.\nThe trigger was need for creating good data set for testing changes in a full text search. I had to locate few hundred of obsolete technical documents to be used as test data, dump the metadata as well as the BLOB data to disc, create INSERT sql scripts and loader that would from Ant pre-load the database with the test set and insert the BLOB's. It is fairly simple task, the issue were boundary conditions:\nDatabase in question is Oracle. I have no OCI8 installed on my MBP and refuse to install Oracle on OS-X - it was little fun getting it up and running on Linux. Usually I run Oracle in Windows or Linux VM and with lack of OCI8, only option how to communicate with it is Level 4 JDBC driver.\nBecause of missing OCI8, Ruby was out of question (the gems for Oracle access needs OCI). So was PL/SQL, for the reason of administator priviledges. I am not exactly a PL/SQL programmer, but know enough to write stored proc that loads or unloads BLOB, assumed that UTL_FILE and DBMS_LOB packages are available and accessible. Which was not the case.\nBefore falling to default and writing it all in Java (which would work, but take certainly longer than I was willing to invest), I decided try out this Groovy thing :-). My exposure to the language was minimal - I never programmed in it (not counting 2 hours spent browsing Ruby in Action), but I hoped that similarity with Java and almighty Google will help me out ...\nConnecting to database in Groovy is simple and elegant:\n[sourcecode language='java']\nimport groovy.sql.Sql\ndb = Sql.newInstance(\n'jdbc:oracle:thin:@myoraclehost:1521:XE',\n'USER', 'PWD', 'oracle.jdbc.driver.OracleDriver')\ndef sql = \"\"\"\nselect d1.document_id, d1.version, d1.filename from document d1\nwhere d1.document_id in ...\n.... REST OF SQL DELETED ....\n\"\"\"\nlist = db.rows(sql)\n[/sourcecode]\nThe result is hash-like structure that can be used to drive both generating the DELETE and INSERT SQL statements into text file as well as retrieving the BLOB's and saving them to HDD:\n[sourcecode language='java']\ndef writeBlobToFile(db, docid, version, filename, reallyWrite=false) {\ndef sqlString = \"SELECT d.DOCUMENT_BODY FROM document d where d.document_id = '$docid' and version = $version\"\ndef row = db.firstRow(sqlString)\ndef blob = (oracle.sql.BLOB)row[0]\ndef byte_stream = blob.getBinaryStream()\nif( byte_stream == null ) { println \"Error for ${docid} : ${version}\" }\nint total = blob.length();\n// Write to a file\nif (reallyWrite) {\nbyte[] byte_array = new byte[total]\nint bytes_read = byte_stream.read(byte_array)\ndef fullname = \"/Users/miro/tmp/BLOBS/$filename\"\ndef fos= new FileOutputStream(fullname)\nfos.write(byte_array);\nfos.close()\n}\nprintln \"Document $docid:$version, file: $filename, size $total\"\nreturn total\n}\n[/sourcecode]\nLoading the documents and metadata from disk to database is done by Ant script\n[sourcecode language='xml']\n[/sourcecode]\nThe Groovy task must be defined before used (with proper classpath). The groovy\ntask shows passing arguments and executing script. The most important part of\nthe script (loading binary file and inserting the BLOB) is here:\n[sourcecode language='java']\n// each line in METADATA.TXT looks like this:\nreg = /document_id: \\'(\\w+)\\', version: (\\d+), filename: \\'(.+)\\', size: (\\d+)/\ndb = Sql.newInstance(\n'jdbc:oracle:thin:@myoraclehost:1521:XE',\n'USER', 'PWD', 'oracle.jdbc.driver.OracleDriver')\ncounter = 0\nnew File(args[1]).eachLine { line -\u0026gt;\nline.eachMatch(reg) { match -\u0026gt;\ntry {\nstr = \"${args[0]}/${match[3]}\"\nprintln \"Opening file: ${str}\"\nFileInputStream fis = new FileInputStream(str)\nint size = fis.available()\nbyte[] data = new byte[size]\nfis.read(data)\n// get the BLOB\nrow = db.firstRow(\"select document_body from document where document_id = ? and version = ? for update\",\n[match[1], match[2]])\nmy_blob = (oracle.sql.BLOB)row[0]\nif( my_blob == null ) println \"my_blob is null!\"\noutstream = my_blob.getBinaryOutputStream();\noutstream.write(data);\noutstream.close()\nfis.close()\ncounter = counter+1\n} catch (Exception e) {\nprint \"Exception: ${e}\\n\"\n}\n}\nprintln \"Processed files: ${counter}\"\n[/sourcecode]\nThe loader is controlled by the file METADATA.TXT that contains information linking document metadata in database (inserted by SQL statement) with file on disk. This indirect way allows easily \"inject\" document body with required search phrases, reload database and run tests.\nThe whole experience was quite pleasant and considering how little I knew about Groovy, it took very little time to create something useful. I wish I could have done some thing in Ruby (which I still like better) - but I was amazed how powerful the combination of Groovy + Ant can be.\nThe most valuable feature is no need to add anything really new or exotic to Java environment - all you need is Jar file and Eclipse plugin, no new/different library packaging scheme - Jars are still jars, not gems.\nThe only minor hickup and weird thing I found was passing arguments between Ant and Groovy script. It looks like that the groovy script should be a script and not use classes + static main method (which would be natural instinct for Java developer). Thanks to Christopher Judd for the hint.\n","date":"April 7, 2008","externalUrl":null,"permalink":"/posts/2008-04-07-trying-out-groovy-with-oracle-database/","section":"Posts","summary":"There is a saying that necessity is the mother of invention. Such necessity happened last week and forced me to try out the Groovy language.\nThe trigger was need for creating good data set for testing changes in a full text search. I had to locate few hundred of obsolete technical documents to be used as test data, dump the metadata as well as the BLOB data to disc, create INSERT sql scripts and loader that would from Ant pre-load the database with the test set and insert the BLOB's. It is fairly simple task, the issue were boundary conditions:\n","title":"Trying out Groovy with Oracle database","type":"post"},{"content":"With the walking season almost upon us (so far only walks by streets, for the Ottawa River Pathway one still needs a snowshoes), it is time to replenish the stock of listening material. Here are some of the about 10 new podcasts that I tried out recently and decided to keep:\n1) Pragmatic Programmers podcast. That was a pleasant find (thanks Milos). The topics covered are very wide - as are topics covered by the books. Average lengths is about half hour and the podcasts appear about 1-2 per month. I really liked the interviews with Michael Nygard and Johanna Rothman. The disadvantage of these podcasts is fairly miserable audio quality - the discussions are done by phone or something is wrong with the recording. Maybe I am spoiled by great professional audio of most of the TWIT network podcasts - but after Leo and the gang, this audio is really hard on ears.\n2) Fortunately, the second podcast - WebDevRadio.com does not suffer from bad audio quality. Topics covered is as name says and as added bonus, web site provides links to episodes.\n3) Late Night Cocoa is podcast focusing on Mac development with Objective C and Cocoa. There is also screencast available.\n4) The series of podcasts on InformIT: so far I tried out OnOpenSource and found it quite interesting. Technically, it is a video podcast. But in reality, you will not loose much if you just listen to it, because the video adds little to information value: two guys sitting and talking. While it is interesting to see how the people from Open Source project look like, it is not really necessary to watch the full interview - it is what they say that counts. Main disadvantage of this podcast on iPod Touch is that you have to let the screen switched on which eats battery much faster. Not ideal while walking.\nIf you happen to be able to understand Czech, the group of guys in Prague is publishing Java centric podcast named Java Portal. Audio quality varies, content is surprisingly good. Prague is large spot on world map of software development centers that contributed a lot to projects like Netbeans or IntelliJIDEA.\nFor me I found that it is very refreshing to listen to podcasts in other languages than English. Without satellite television available carrying TV stations from the old country I have lost contact with everyday living Czech language. If you feel the same, give Java Portal a try. I am now in a search for good tech podcast in German. Any recommendations ?\n","date":"April 2, 2008","externalUrl":null,"permalink":"/posts/2008-04-02-couple-of-new-podcasts/","section":"Posts","summary":"With the walking season almost upon us (so far only walks by streets, for the Ottawa River Pathway one still needs a snowshoes), it is time to replenish the stock of listening material. Here are some of the about 10 new podcasts that I tried out recently and decided to keep:\n1) Pragmatic Programmers podcast. That was a pleasant find (thanks Milos). The topics covered are very wide - as are topics covered by the books. Average lengths is about half hour and the podcasts appear about 1-2 per month. I really liked the interviews with Michael Nygard and Johanna Rothman. The disadvantage of these podcasts is fairly miserable audio quality - the discussions are done by phone or something is wrong with the recording. Maybe I am spoiled by great professional audio of most of the TWIT network podcasts - but after Leo and the gang, this audio is really hard on ears.\n","title":"Couple of new podcasts","type":"post"},{"content":"Here it comes, first occurence: one of my VM's BSOD-ed on me yesterday.\nTo be completely fair, I did have experienced an occurrence of something similar twice in last moths: after wake up from sleep, the screen was collection of the color pixels, completely unreadable. After reboot, everything was normal.\nI found out that the issue may be related to the \"safesleep\" mode. For now, I disabled the mode by\nsudo pmset -a hibernatemode 0\nTo re-enable SafeSleep, the command is:\nsudo pmset -a hibernatemode 3\nSo far, everything works - but I am still investigating. Thanks to this thread (in German) for the hint.\n","date":"March 29, 2008","externalUrl":null,"permalink":"/posts/2008-03-29-blue-screen-of-the-death-on-a-mac/","section":"Posts","summary":"Here it comes, first occurence: one of my VM's BSOD-ed on me yesterday.\nTo be completely fair, I did have experienced an occurrence of something similar twice in last moths: after wake up from sleep, the screen was collection of the color pixels, completely unreadable. After reboot, everything was normal.\nI found out that the issue may be related to the \"safesleep\" mode. For now, I disabled the mode by\n","title":"Blue screen of the death on a Mac","type":"post"},{"content":"I did not even notice that the visit counter left the 16 bit domain sometimes during last few days. Now it shows about 67 000 visits. Honestly, I am pleasantly surprised how many people found this blog worthy their time :-). Thanks to you all ...\nNext boundary is of course 128K, 256K, 512K hits and finally a \"Megahit\". But that's far far away.\n","date":"March 26, 2008","externalUrl":null,"permalink":"/posts/2008-03-26-finally-over-16/","section":"Posts","summary":"I did not even notice that the visit counter left the 16 bit domain sometimes during last few days. Now it shows about 67 000 visits. Honestly, I am pleasantly surprised how many people found this blog worthy their time :-). Thanks to you all ...\nNext boundary is of course 128K, 256K, 512K hits and finally a \"Megahit\". But that's far far away.\n","title":"Finally over 16 :-)","type":"post"},{"content":"Akita published two part tutorial that leads you through building the famous 15 minute blog application in Rails 2.0. Read the parts one and two - or follow the screencast by the same author.\nThanks a lot, Akita - very nicely done !\n","date":"March 25, 2008","externalUrl":null,"permalink":"/posts/2008-03-25-rails-2-really-good-tutorial/","section":"Posts","summary":"Akita published two part tutorial that leads you through building the famous 15 minute blog application in Rails 2.0. Read the parts one and two - or follow the screencast by the same author.\nThanks a lot, Akita - very nicely done !\n","title":"Rails 2 - really good tutorial","type":"post"},{"content":"I have first time encountered the error:\nORA-29907: found duplicate labels in primary invocations\nafter testing the change request we have implemented recently. The error message was not very helpful - I was not exactly sure which labels and which invocations ;-) - and as Oracle guru who actually does understand fine details of Oracle Text was visiting sunny India, I was on my own.\nThe change addressed an issue in repository search: users were asking for more flexible processing of full text search phrases: instead of e.g. searching for \"unit test\" search for document that contains both unit AND test. The text was parsed in Java and the SQL generator produced instead of something like\n[sourcecode language='sql']\nSELECT * FROM DOCUMENT d1 WHERE ROWNUM 5)\n[/sourcecode]\n[sourcecode language='sql']\nSELECT * FROM DOCUMENT d1 WHERE ROWNUM 5)\nAND ( CONTAINS(d1.document,'unit',1) \u0026gt; 5)\n[/sourcecode]I am still unsure what primary invocation is, but the above mentioned 'label' was the number one. After changing the generator to issue sequence numbers in the CONTAINS, everything worked OK:\n[sourcecode language='sql']\nSELECT * FROM DOCUMENT d1 WHERE ROWNUM 5)\nAND ( CONTAINS(d1.document,'unit',2) \u0026gt; 5)\n[/sourcecode]\n","date":"March 19, 2008","externalUrl":null,"permalink":"/posts/2008-03-19-the-meaning-of-ora-29907-error-and-the-fix/","section":"Posts","summary":"I have first time encountered the error:\nORA-29907: found duplicate labels in primary invocations\nafter testing the change request we have implemented recently. The error message was not very helpful - I was not exactly sure which labels and which invocations ;-) - and as Oracle guru who actually does understand fine details of Oracle Text was visiting sunny India, I was on my own.\nThe change addressed an issue in repository search: users were asking for more flexible processing of full text search phrases: instead of e.g. searching for \"unit test\" search for document that contains both unit AND test. The text was parsed in Java and the SQL generator produced instead of something like\n","title":"The meaning of ORA-29907 error and the fix","type":"post"},{"content":"After some break, I got back to Rails land. The return is not as smooth as I hoped: since Rails 2.0, many things work differently and quite a few steps learned from \"The Book\" do not work any more. The issues are more often than not quite easy to fix, but there is quite a few of them.\nAll the following is related to NetbeansRuby build 6327 from Jan 26th with JRuby 1.1RC1\nAfter installing NetbeansRuby and updating the Gems (Tools-\u0026gt;Ruby Gems), the attempt to generate Rails application fails:\n[sourcecode language='xml']\n/Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:379:in `report_activate_error': Could not find RubyGem activeresource (= 2.0.2) (Gem::LoadError)\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:311:in `activate'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:337:in `activate'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `each'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `activate'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:336:in `active_gem_with_options'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/site_ruby/1.8/rubygems.rb:50:in `gem'\nfrom /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/rails:18\n[/sourcecode]\nLooks like the gem updater somehow missed activeresource - maybe a problem with dependencies ?To fix this, manually install activeresource 2.0.2 - Tools -\u0026gt; Ruby Gems, New Gems, search for resource, install. This is list of the installed gems:\nactionmailer (2.0.2, 1.3.5) actionpack (2.0.2, 1.13.5) actionwebservice (1.2.6, 1.2.5) activerecord (2.0.2, 1.15.5) activerecord-jdbc-adapter (0.7.2, 0.7) activeresource (2.0.2) activesupport (2.0.2, 1.4.4) jruby-openssl (0.1.1) rails (2.0.2, 1.2.5) rake (0.8.1, 0.7.3) rspec (1.1.3, 1.1.1) sources (0.0.1) By default, the Rails 2 selects Sqlite3 database. This is great choice if you use C-Ruby, but not so great for JRuby - see this post. After few frustrated attempts to find workaround, I decided to go with Ruby 1.8.6, updated (again) the Gems in system installation (the first updated upgraded JRuby gems) and decided to try out the Depot sample - just have something that works, rather than fighting with issues of both Rails 2 and my own bugs. To keep with the book, I stayed with MySQL (quietly running in VMWare virtual machine).\nBy the book I have generated Product model and Admin controller, but instead of seeing familiar screen, Rails responded with error:\n[sourcecode language='xml']\nRouting Error\nNo route matches \"/admin\" with {:method=\u0026gt;:get}\n[/sourcecode]\nThis can be fixed by addingmap.connect ':controller/:action'to routes.rb, but this is probably bad idea because it goes against REST design principles which Rails 2 tries to promote. But to go ahead with the example, I hacked it :-) and added scaffolding. Next error I got was:\n[sourcecode language='xml']\nNoMethodError in AdminController#index\nundefined method `scaffold' for AdminController:Class\nRAILS_ROOT: /Users/miro/Projects/RAILS2/Depot\nApplication Trace | Framework Trace | Full Trace\napp/controllers/admin_controller.rb:2\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_without_new_constant_marking'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:203:in `load_file'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:342:in `new_constants_in'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:202:in `load_file'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:94:in `require_or_load'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:248:in `load_missing_constant'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:453:in `const_missing'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/dependencies.rb:465:in `const_missing'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/inflector.rb:257:in `constantize'\n/Library/Ruby/Gems/1.8/gems/activesupport-2.0.2/lib/active_support/core_ext/string/inflections.rb:148:in `constantize'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/routing.rb:1426:in `recognize'\n[/sourcecode]\nScaffolding is one of the parts removed in Rails 2. :-(. I tried to install 'scaffolding', which led to another error:\n[sourcecode language='xml']\nNoMethodError in AdminController#index\nundefined method `paginate' for #\nRAILS_ROOT: /Users/miro/Projects/RAILS2/Depot\nApplication Trace | Framework Trace | Full Trace\nvendor/plugins/scaffolding/lib/scaffolding.rb:107:in `list'\nvendor/plugins/scaffolding/lib/scaffolding.rb:95:in `index'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `send'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `perform_action_without_filters'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in `call_filters'\n[/sourcecode]\nBased on this post, I installed classic_pagination, which resulted in another error when trying to enter new Product\n[sourcecode language='xml']\nActionController::InvalidAuthenticityToken in AdminController#create\nActionController::InvalidAuthenticityToken\nRAILS_ROOT: /Users/miro/Projects/RAILS2/Depot\nApplication Trace | Framework Trace | Full Trace\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/request_forgery_protection.rb:79:in `verify_authenticity_token'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:469:in `send!'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:469:in `call'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:441:in `run'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:716:in `run_before_filters'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:695:in `call_filters'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in `perform_action_without_benchmark'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'\n/Library/Ruby/Gems/1.8/gems/actionpack-2.0.2/lib/action_controller/rescue.rb:199:in `perform_action_without_caching'[/sourcecode]\nI backtracked, and tried to go with generated scaffold, rather with dynamic. The generated views were named edit.html.erb, rather than edit.rhtml and the generator did not allow to enter controller (second argument). This lead to error\n[sourcecode language='xml']\nError:\nTemplate is missing\nMissing template admin/index.html.erb in view path /Users/miro/Projects/RAILS2/Depot/app/views\n[/sourcecode]\nAt this point I gave up and decided to:\nread the Rails 2.0 documentation (after everything else failed, read the manual ...) reconsider using AWDWR as the guide - obviously, it needs to be updated to be useful with Rails 2. If you purchased the PDF from Pargmatic Programmers, there is an update available on their website, but it is not an update for Rails 2 ... I was not the only person to try AWDWR with Rails 2. The best resource I found was Ruby Plus website with series of screencasts, starting with this. The author - Bala Paranj did great job in putting together very useful collection of Rails screencasts. If you want to use the AWDWR with Rails 2.0, listen to them first - unless you are very experienced Rails developer.\n","date":"March 17, 2008","externalUrl":null,"permalink":"/posts/2008-03-17-starting-ruby-on-rails-2-with-netbeans-and-awdwr-book/","section":"Posts","summary":"After some break, I got back to Rails land. The return is not as smooth as I hoped: since Rails 2.0, many things work differently and quite a few steps learned from \"The Book\" do not work any more. The issues are more often than not quite easy to fix, but there is quite a few of them.\nAll the following is related to NetbeansRuby build 6327 from Jan 26th with JRuby 1.1RC1\n","title":"Starting Ruby on Rails 2 with Netbeans and AWDWR book","type":"post"},{"content":"After some break, I dusted off the Ruby to try out one interesting idea Peter presented yesterday that literally ASKS for Rails. So I grabbed the latest and greatest RubyNetBeans from Ruby Hudson. For some reason it stopped updates on January 26th so the latest version I have got was build 6327. It is bundled with JRuby 1.1RC1 and the Rails version that comes preinstalled is 1.2.6. Using the menu Tools -\u0026gt; Ruby Gems, they can be easily upgraded to latest and greatest 2.0.2.\nThe trouble begins when you want to install database connectivity gems such as sqlite3-ruby. The installer fails with the message:\n[sourcecode language='xml']\ntrying to install\nINFO: `gem install -y` is now default and will be removed\nINFO: use --ignore-dependencies to install only the gems you list\nBuilding native extensions. This could take a while...\nextconf.rb:1: no such file to load -- mkmf (LoadError)\nERROR: Error installing sqlite3-ruby:\nERROR: Failed to build gem native extension.\n/Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/bin/jruby extconf.rb install sqlite3-ruby --no-rdoc --no-ri --include-dependencies --version \u0026gt; 0\nGem files will remain installed in /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1 for inspection.\nResults logged to /Users/miro/Applications/RubyNetBeans.app/Contents/Resources/nbrubyide/ruby1/jruby-1.1RC1/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.1/ext/sqlite3_api/gem_make.out\n[/sourcecode]The missing file mkmf.rb is indeed missing from the JRuby distribution. This is entered as a bug in JIRA 1306 with resolution 'Won't fix'. Tough luck.\nI understand the reasons and motivation for this decision - the JRuby team decided not to support native extensions in Gems, to keep the platform Java only. I also understand that in this particular case, there are workarounds - using ActiveRecord-DBC gem and JDBC drivers for the database will most likely work. Unfortunately, this decision makes choice of JRuby as platform very questionable.\nI really liked JRuby for the comfort of having platform that is portable and safely wrapped within boundaries of the good old trusted JVM. I feel much more comfortable maintaining possibly several different versions of JRuby and corresponding Gems sets than maintaining same several configurations on the OS level and sudo-ing just to install Gems. I was more that happy to trade the lack of speed for this security.\nThe two main attractions of Ruby (from my point of view) are elegant, powerful language with beautiful syntax as well as sheer amount of code available as Gems to be reused. With the bug 1306, many of this code may not be available for JRuby - unless Gem authors make specific provisions for Java version of the Gem. I cannot think how this is a good idea and certainly not a good news for the future of the language.\nOne way out is use native Ruby interpreter, of course and make sure you do not mess up your installation by trying out new things. This does not allow the easy way into enterprise that JRuby was promising - by being basically 'just another jar' and running on Tomcat.\nThe other way out is to reconsider the Groovy. I still do not enjoy the syntax anywhere close to Ruby, but every Groovy class is Java class, there is no need for artificial bridges. It has own clone of Rails - GRails - that seems to provide lots of Rails magic and goodies and is based on Spring which I am very familiar and quite happy with. I still do not know whether the amount of \"gems\" in Groovy world is in the same league as Ruby (which is still limited compared to Python or even CPAN Perl bonanza) - but as long as I can find that what I need, it may be just enough.\nFor now, I will revert back to Ruby (no time to start learning Groovy+Grails), but I definitely will look at it later on.\n","date":"March 16, 2008","externalUrl":null,"permalink":"/posts/2008-03-16-showstopper-issue-with-jruby/","section":"Posts","summary":"After some break, I dusted off the Ruby to try out one interesting idea Peter presented yesterday that literally ASKS for Rails. So I grabbed the latest and greatest RubyNetBeans from Ruby Hudson. For some reason it stopped updates on January 26th so the latest version I have got was build 6327. It is bundled with JRuby 1.1RC1 and the Rails version that comes preinstalled is 1.2.6. Using the menu Tools -\u003e Ruby Gems, they can be easily upgraded to latest and greatest 2.0.2.\n","title":"Showstopper issue with JRuby ?","type":"post"},{"content":"Guess what are three most useful tools without which no proper Ottawa household can exist ? Snow shovel, snow pusher and car window ice scratcher. If the number was 4, the next would be snowblower. Up to yesterday, our family was in safe position being equipped with several shovels, four or five scratchers and one pusher.\nThen disaster stroke: my son broke the pusher while moving away few cube meters of snow we removed from the roof. In case you do not understand - removing snow from roof is another favorite winter leisure time activity in Ottawa: almost everybody is doing it. Not that it would be so much fun, but because of the dreadful consequences - avoid it and you may end up like this guy.\nEspecially in year rich on snow, like this one. And this winter - despite beig warm and cosy, only few days of -25 and below - it is snow-wise very likely a record year. The previous record winter happened (fortunately) long before I set foot on this continent: in 1970-71, we had 444 cm of snow during winter. Right now, it is about 415. The weather forecast for next week mentions possibility of another 50 cm. Ouch.\nThe shoveling is no fun at all. The back garden is full of snow, with top of the snowhill well over 3 m high. Another mountain in front of the house. I can hardly imagine where we do put another 50 cm, and most importantly HOW. Because the darn pusher is broken.\nNow if you think that in modern market economy it is just a matter of driving to next store and buying one, think again. This is what I did today, just to discover that full Garden and Outdoor section is filled with barbecues, rakes, seeds, lawn movers and other completely ridiculous tools :-). No pushers at all. Only small pack of deserted shovels set aside. I bought one to make the trip worth the time ....\nI guess I will have to BORROW a pusher from neighbor :-(. What a shame to admit I am pusher-less ...\nOut of desperation, I have decided to share my experience with the public in the following book:\n","date":"March 13, 2008","externalUrl":null,"permalink":"/posts/2008-03-13-on-white-stuff-and-other-disasters/","section":"Posts","summary":"Guess what are three most useful tools without which no proper Ottawa household can exist ? Snow shovel, snow pusher and car window ice scratcher. If the number was 4, the next would be snowblower. Up to yesterday, our family was in safe position being equipped with several shovels, four or five scratchers and one pusher.\nThen disaster stroke: my son broke the pusher while moving away few cube meters of snow we removed from the roof. In case you do not understand - removing snow from roof is another favorite winter leisure time activity in Ottawa: almost everybody is doing it. Not that it would be so much fun, but because of the dreadful consequences - avoid it and you may end up like this guy.\n","title":"On White Stuff and Other Disasters","type":"post"},{"content":"Lured by the iPhone platform, this is what I read in the evenings. Feels kind of funny: after 10+ years of Java/C# and almost as many years of C++ beforehand, I mostly lost my C instincts and C habits. Fortunately, I have also mostly lost my C++ bad habits as well.\nThe Apple site is definitive starting point - put the http://developer.apple.com/referencelibrary/index.html into your bookmarks. From non-Apple sources, very bookmarking-worthy is the Cocoa Literature and Cocoa Devcentral.\nTheocacao has a nice example highlighting diferences between Objective C 1.0 and 2.0. There are many tutorials available, with various depth and quality, e.g. here, and here. Wikipedia page is also quite useful.\nFrom books - I have browsed few in Chapters and on Safari Books, the best still seems to be Hillegass's book. There is an updated version (for Objective C 2.0) coming out in June 2008.\nFrom list of links, try this.\n","date":"March 12, 2008","externalUrl":null,"permalink":"/posts/2008-03-12-couple-of-objective-c-and-cocoa-links/","section":"Posts","summary":"Lured by the iPhone platform, this is what I read in the evenings. Feels kind of funny: after 10+ years of Java/C# and almost as many years of C++ beforehand, I mostly lost my C instincts and C habits. Fortunately, I have also mostly lost my C++ bad habits as well.\nThe Apple site is definitive starting point - put the http://developer.apple.com/referencelibrary/index.html into your bookmarks. From non-Apple sources, very bookmarking-worthy is the Cocoa Literature and Cocoa Devcentral.\n","title":"Couple of Objective-C and Cocoa links","type":"post"},{"content":"This is post is NOT about version control in the sense of source code control. It addresses the issue how to easily tell which version of the Web application is running as well make sure that the same version is reflected in the snapshots performed by Ant. We have used this approach on several applications and found it quite useful.\nThe version I talk about is not the automatically generated version from VCS system (such as SVN revision). The version number is set manually.\nIn every project, we include property file named application.properties, placed at the root of the classpath (next to 'com' directory in the source tree). The content can look like this\n[sourcecode language='java']\napp.name = MyApp\napp.version = 0.5.4\napp.info = User authentication implemented\n[/sourcecode]This property file will be available to Java code because of its location in classpath. Our build.xml file ususally starts with few includes like this\n[sourcecode language='xml']\n...\n[/sourcecode]We try to load first the property files named after the computer. This way we can easily address differences in e.g. Tomcat locations, pathnames to libraries etc. This is very useful if not all team members have identical development environment - which is almost always the case, as I am on Mac and the others mostly on Windows :-). The environment variable COMPUTERNAME is automatically set for you if you are on Windows, for Mac/Linux users all you need is an export in your .bashrc file.\nThe second include loads the application properties and makes the 'app.version', 'app.name' available for Ant tasks. Externalizing the app.name allows reusing same Ant script for multiple project. Here is an example of the task that creates and archive of current source code snapshot using this information:\n[sourcecode language='xml']\n[/sourcecode]The DSTAMP and TSTAMP are set in prepare task:\n[sourcecode language='xml']\n[/sourcecode]To access the information from application.properties, we simply add it to the list of message sources:\n[sourcecode language='xml']\nmessages\napplication\n[/sourcecode]This allows to easily display the version number and information as part of e.g. JSP page:\n[sourcecode language='xml']\n-\n[/sourcecode]For production, I usually still leave the version in the JSP, only include it in HTML comments, so that it does not interfere with the UI but is still accessible by viewing page source.\nI usually set version number and info string manually, but it possible to automatically write information about e.g. build date and time of the application and make it a part of the version info. To do that, use the Ant task:\n[sourcecode language='xml']\nFile test.properties updated at ${DSTAMP} ${TSTAMP}\n[/sourcecode]In this case, the value of property app.stamp will be overwritten every time the 'set_version' task executes.\n","date":"March 10, 2008","externalUrl":null,"permalink":"/posts/2008-03-10-versioning-with-spring-and-ant/","section":"Posts","summary":"This is post is NOT about version control in the sense of source code control. It addresses the issue how to easily tell which version of the Web application is running as well make sure that the same version is reflected in the snapshots performed by Ant. We have used this approach on several applications and found it quite useful.\nThe version I talk about is not the automatically generated version from VCS system (such as SVN revision). The version number is set manually.\n","title":"Versioning with Spring and Ant","type":"post"},{"content":"I better blog this before I forget what was the issue :-).\nDuring daily run of unit tests, I started to receive this (very well explained) exception:\n[sourcecode language='xml']\norg.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [17004];\n--- The error occurred while applying a parameter map.\n--- Check the APPROVAL_TASK.insert-InlineParameterMap.\n--- Check the parameter mapping for the 'scheduledDate' property.\n--- Cause: java.sql.SQLException: Invalid column type; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:\n--- The error occurred while applying a parameter map.\n--- Check the APPROVAL_TASK.insert-InlineParameterMap.\n--- Check the parameter mapping for the 'scheduledDate' property.\n--- Cause: java.sql.SQLException: Invalid column type\nat org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:121)\nat org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)\nat org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)\nat org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:397)\n... [/sourcecode]\nNow the problem was that scheduledDate was null. Here is partial SQL map used:\n[sourcecode language='xml']\ninsert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)\nvalues (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:DATETIME#)\n[/sourcecode]The createDate time jdbcType DATETIME was actually one of my changes. What Abator generated originally was this:\n[sourcecode language='xml']\ninsert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE)\nvalues (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:DATE#)\n[/sourcecode]This map does not suffer by the Null value problem, but unfortunately does not store the time portion of the date - which was the main reason why I used DATETIME, unaware of the Null sensitivity. There are three ways how to fix this. First is obvious - do use DATETIME and make sure that the field has value. This may be good enough as long as you do not need to save null values. Second solution is to keep DATETIME and use iBatis magic with conditionals in map definition: [sourcecode language='xml'] insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE) values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, null #createDate:DATETIME# ) [/sourcecode] This deals with the null value differently and avoids \"guessing\" the column type, which caused the problem.Third solution may not work on other databases, but on Oracle works prefectly. The data type TIMESTAMP does both store the time portion as well as handles Null values without any problems. This is what I used at the end. Final map: [sourcecode language='xml'] insert into APPROVAL_TASK (APPR_ID, STEP, TASK, EMAIL_TO, CREATE_DATE) values (#apprId:DECIMAL#, #step:DECIMAL#, #task:DECIMAL#, #emailTo:VARCHAR#, #createDate:TIMESTAMP#) [/sourcecode] ","date":"March 7, 2008","externalUrl":null,"permalink":"/posts/2008-03-07-ibatis-date-null-values-and-oracle/","section":"Posts","summary":"I better blog this before I forget what was the issue :-).\nDuring daily run of unit tests, I started to receive this (very well explained) exception:\n[sourcecode language='xml']\norg.springframework.jdbc.UncategorizedSQLException: SqlMapClient operation; uncategorized SQLException for SQL []; SQL state [null]; error code [17004];\n--- The error occurred while applying a parameter map.\n--- Check the APPROVAL_TASK.insert-InlineParameterMap.\n--- Check the parameter mapping for the 'scheduledDate' property.\n--- Cause: java.sql.SQLException: Invalid column type; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:\n--- The error occurred while applying a parameter map.\n--- Check the APPROVAL_TASK.insert-InlineParameterMap.\n--- Check the parameter mapping for the 'scheduledDate' property.\n--- Cause: java.sql.SQLException: Invalid column type\nat org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.translate(SQLStateSQLExceptionTranslator.java:121)\nat org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:322)\nat org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)\nat org.springframework.orm.ibatis.SqlMapClientTemplate.insert(SqlMapClientTemplate.java:397)\n... [/sourcecode]\nNow the problem was that scheduledDate was null. Here is partial SQL map used:\n[sourcecode language='xml']\n","title":"iBatis, Date null values and Oracle","type":"post"},{"content":"Testing applications that communicate using email is more challenging than e.g. testing database access. Thanks to GMail and Spring, it can be done pretty easily.\nHere is the scoop: I need to generate email notifying users about business events and after sending the email, store the content in the database. In real environment you will use corporate SMTP server and real email addresses of real people.\nFor development we can avoid bothering and spamming our customers by few simple tricks.\nFirst step is to get new GMail account. Name it e.g. Company.Notifier or something easily distinguishable. In Spring, configure the sender bean:\n[sourcecode language='xml']\nsmtp.gmail.com\ntrue\ntrue\n25000\ncompany.notifier\nsecret\n[/sourcecode]\nThe port can have value 25 (default) - but if you are using ISP provider such as Rogers, chances are the default port is blocked for outgoing connections - you can use port 587 instead.Second piece is component that actually uses the mailSender: notificationService.\n[sourcecode language='xml']\nmiro.adamy+alwaysCC@thinknostic.com\n.... deleted ...\n[/sourcecode]\nNote the velocityEngine bean that is used to generate the body of the email from the template. The 'alwaysCCList' property is using nice little trick available with GMail: if you send email to YOURNAME+anything@gmail.com, the '+anything' will be ignored but kept with email and it will arrive as if the address were just YOURNAME@gmail.com. You can use the postfix to find or autotag the emails.The code that sends email is actually pretty simple (the method of the notificationService)\n[sourcecode language='java']\npublic EmailContent sendNotificationEmail(EmailParameters params, EmailContent _content, boolean isDryRun) {\nfinal EmailContent c = mergeTemplate(params, _content);\nMimeMessagePreparator preparator = new MimeMessagePreparator() {\npublic void prepare(MimeMessage mimeMessage) throws Exception {\nMimeMessageHelper message = new MimeMessageHelper(mimeMessage);\nmessage.setTo(c.getEmailTo());\nmessage.setFrom(\"DO-NOT-REPLY@company.com\"); // could be parameterized...\nmessage.setText(c.getEmailBody(), true);\nmessage.setSubject(c.getEmailSubject());\nif (alwaysCCList != null \u0026amp;\u0026amp; alwaysCCList.size() \u0026gt; 0) {\nmessage.setCc(alwaysCCList.toArray(new String[0]));\nc.setEmailCcFromList(alwaysCCList);\n}\n...\n}\n};\nif (isDryRun || emailsToFile)\n{\n// save to file\n...\n}\nif (!isDryRun)\nthis.mailSender.send(preparator);\nreturn c;\n}\n[/sourcecode]\nThe class EmailContent is container for email address, subject, body, CC list.\nIt gets created as empty class with only recipient name and email address passed from business method as well as name of the Velocity template that is used to render email body. The method mergeTemplate loads the Velocity template and renders the actual email body, using the parameters (which is more or less) a hash map, cotaining e.g. URL's or information that needs to be inserted to email. The generated content is stored back to EmailContent, which will be after successful delivery written to database for audit and archiving purposes.If you are JavaScript or Ruby programmer, you will immediately recognize the 'functor' pattern: preparator is set to instance of anonymous inner class and is used with configured preparator.The actual rendering of the content using Velocity can be done like this:\n[sourcecode language='java']\nprivate EmailContent mergeTemplate( EmailParameters params, EmailContent content) {\nMap model = new HashMap();\nmodel.put(\"param\", params);\nmodel.put(\"content\", content);\nString text = \"MISSING TEXT\";\nString subject = \"Notification email\";\nString template = content.getTemplateId();\ntry {\n// get subject line\nif (template_names.containsKey(template)) {\nsubject = template_names.get(template);\nVelocityContext velocityContext = new VelocityContext(model);\nStringWriter writer = new StringWriter ( ) ;\nPrintWriter out = new PrintWriter ( writer ) ;\nVelocity.evaluate(velocityContext, out, \"subject\", new StringReader(subject));\nsubject = writer.toString();\nmodel.put(\"subjectLine\", subject);\n// now the body\ntext = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,\n\"com/thinknostic/APP/service/email/\"+template, model);\n}\nelse {\n// TODO: log configuration error - template not found\n}\ncontent.setEmailBody(text);\ncontent.setEmailSubject(subject);\nreturn content;\n} catch (VelocityException e) {\n// back to untranslated\n// TODO: error report\n// subject = params.subject;\n} catch (IOException e) {\n// TODO Auto-generated catch block\ne.printStackTrace();\n}\nreturn null;\n}\n[/sourcecode]\nIn the above, template id is actual file name with body of the HTML email and the hashmap template_names (configured in Spring XML) maps the id to another string, which is then used as subject line. Both body and subject can contain macros.\nNote: if you get conflict on ${} syntax, see this entry.\nNow, finally - how do we test this ? It is quite easy, thanks to JUnit support in Spring.\n[sourcecode language='java']\n@ContextConfiguration(locations={\"/com/thinknostic/APP/test/test-context.xml\",\n\"/com/thinknostic/APP/test/service/NotificationTests-context.xml\"})\npublic class NotificationTests extends AbstractTransactionalJUnit4SpringContextTests {\n@Autowired\nNotificationServiceImpl notificationService;\npublic NotificationServiceImpl getNotificationService() {\nreturn notificationService;\n}\npublic void setNotificationService(NotificationServiceImpl notificationService) {\nthis.notificationService = notificationService;\n}\n@Autowired\nApprovalDAO approvalDao;\npublic ApprovalDAO getApprovalDao() {\nreturn approvalDao;\n}\npublic void setApprovalDao(ApprovalDAO approvalDao) {\nthis.approvalDao = approvalDao;\n}\nDocument doc;\nEmailContent cont;\nApproval app;\nApprovalStep step1;\nApprovalStep step2;\n@Before\npublic void createMockApproval() {\nthis.logger.info(\"Before\");\n// controlls whether to use emails\nnotificationService.setReallySend(true);\ndoc = (Document)DocumentInfo.createMockDI(\"103\", 1);\n// create the approval and insert it into\napp = Approval.createMockApproval(1L, doc);\napprovalDao.insert(app);\nstep1 = ApprovalStep.createMockStep(app.getApprId(), 1);\napprovalDao.insert(step1);\nstep2 = ApprovalStep.createMockStep(app.getApprId(), 2);\napprovalDao.insert(step2);\ncont = EmailContent.createMock(app.getApprId(), step1.getStep(), \"miro adamy\", \"miro_adamy@rogers.com\");\n}\n@After\npublic void cleanup() {\nthis.logger.info(\"After\");\n// reset\nnotificationService.setReallySend(false);\ndoc = null;\ncont = null;\napp = null;\nstep1 = null;\nstep2 = null;\n}\nprivate void assertEverything()\n{\nassertTrue(\"The email service is empty\", notificationService != null);\nassertTrue(\"The email parameteres not available\", emailParameters != null);\nassertTrue(\"The document does not exist\", doc != null);\n}\n@Test\npublic void approval_all_cancelled_test() {\ndoc.setFilename(\"approval_all_cancelled\");\nnotificationService.notifyApprovalCancelledAll(doc, cont);\n}\n@Test\npublic void approval_cancelled_test() {\nassertEverything();\ndoc.setFilename(\"approval_cancelled\");\nEmailContent ui = EmailContent.createMock(app.getApprId(), step1.getStep(), \"miro adamy\", \"Miro.Adamy@gmail.com\");\nnotificationService.notifyApprovalCancelled(doc, ui);\n}\n// and so on - many more tests\n....\n}\n[/sourcecode]\nAssumed that your Spring context configuration files defined in annotations are OK, all you have to do is run the suite. The XML defines beans with names corresponding to the test properties and autowiring will take care of the rest.Also notice that @Before method (which runs before each test) actually DOES modify the database and inserts records with same primary key over and over. This works thanks to transaction magic of Spring, which rolls back the inserts at the end of the test.Last thing to mention is using of \"mockXXX\" static methods to generate the instance of object. IT not really a mock object we are creating here, but a well defined instance of business object with some properties parametrized. You can even define it as a bean in Spring context XML, but that is IMHO an overkill - keeping everything in test Java class makes things easier to understand.\nThis method does belong to tests, but it is very convenient just to keep it with domain object. I usually create the 'createMock' method right after I add a new domain object\n","date":"March 5, 2008","externalUrl":null,"permalink":"/posts/2008-03-05-how-to-generate-and-send-emails-using-spring-and-velocity/","section":"Posts","summary":"Testing applications that communicate using email is more challenging than e.g. testing database access. Thanks to GMail and Spring, it can be done pretty easily.\nHere is the scoop: I need to generate email notifying users about business events and after sending the email, store the content in the database. In real environment you will use corporate SMTP server and real email addresses of real people.\nFor development we can avoid bothering and spamming our customers by few simple tricks.\n","title":"How to generate and send emails using Spring and Velocity","type":"post"},{"content":"Part of the configuration magic is (one of several) Spring post-processors, that allows load the property file or files and refer to the values in these files inside XML configuration files. The rationale behind these is that property files are much easier to edit that possibly huge XML config file and using property values prevents repeating same value over and over again. With this approach, the following configuration:\n[sourcecode language='xml']\n[/sourcecode]\ncan be written as\n[sourcecode language='xml']\nWEB-INF/mail.properties\nWEB-INF/jdbc.properties\n[/sourcecode]\nand (in jdbc.properties)\n[sourcecode language='java']\njdbc.username=some_user\njdbc.password=secret[/sourcecode]If you are using in the same project Velocity and want to utilize the VTL macros inside the configured values, the approach above will not work, because PropertyPlaceholderConfigurer will try to replace ALL macros in form ${something} with a value from property file - and throw exception if not found.The solution is easy: you need to switch the prefix of the PropertyPlaceholderConfigurer to something else than the default ${ and avoid conflict wih Velocity. The modified configuration could look like:\n[sourcecode language='xml']\nWEB-INF/mail.properties\nWEB-INF/jdbc.properties\n[/sourcecode]\n","date":"February 25, 2008","externalUrl":null,"permalink":"/posts/2008-02-25-spring-propertyplaceholderconfigurer-with-velocity/","section":"Posts","summary":"Part of the configuration magic is (one of several) Spring post-processors, that allows load the property file or files and refer to the values in these files inside XML configuration files. The rationale behind these is that property files are much easier to edit that possibly huge XML config file and using property values prevents repeating same value over and over again. With this approach, the following configuration:\n[sourcecode language='xml']\n","title":"Spring PropertyPlaceholderConfigurer with Velocity","type":"post"},{"content":"If you work with Oracle database, a very good tool you should not ignore is the Oracle SQL Developer. It gives you much more power when it comes to manipulating data or managing database. I use most of the time MyEclipseIDE plugins, but when I need e.g. export data, the SQLDeveloper is way to go.\nToday I tried it for first time on the Mac. I started to configure and database connection and was completely confused by the error message \"Port must contain numerical value\". Here was the dialog box:\nI typed the hostname:1521 but the error message kept coming back. There was no obvious way how to put 3 values - host, port and SID into two field. After checking the documentation, I remembered that the Windows version did have 3 text fields instead of two.\nWhat was the problem ? The layout manager in Java did unfortunately completely hide one of the 3 fields. After resizing the dialog, all fields would be visible:\nAfter this, everything worked OK.\nObviously, Mac version of the SQLDeveloper could use some minor improvement. For example, the menu looks everything but like a finished Mac application:\n","date":"February 23, 2008","externalUrl":null,"permalink":"/posts/2008-02-23-oracle-sqldeveloper-and-mystery-of-the-missing-host/","section":"Posts","summary":"If you work with Oracle database, a very good tool you should not ignore is the Oracle SQL Developer. It gives you much more power when it comes to manipulating data or managing database. I use most of the time MyEclipseIDE plugins, but when I need e.g. export data, the SQLDeveloper is way to go.\nToday I tried it for first time on the Mac. I started to configure and database connection and was completely confused by the error message \"Port must contain numerical value\". Here was the dialog box:\n","title":"Oracle SQLDeveloper and mystery of the missing host","type":"post"},{"content":"I have been sick for last two weeks, most of the time offline, listening to podcasts and audiobooks and doing more or less nothing. I have caught up with the backlog of episodes, saw lots of videos from Macworld.\nAmong the audiobooks I was listening two, some recommendations:\nThe Company is good parody of the corporate life. Starting with missing donut, it tells the story of a new hire in large corporation, governed by strange rules. It soon has an interesting twist - find for yourself. The book is available as MP3 CD, so you can save time ripping it to iPod.\nAnother book that I liked was cult classic that I have read before (in at least 3 languages), but never heard it: The Dune. Nicely done, and an excellent way how to make time fly faster when you are locked to bed and too sick to do any serious reading or coding :-)\nAs of yesterday, I am back in circulation, trying to catch up with everything I missed for last two weeks.\n","date":"February 22, 2008","externalUrl":null,"permalink":"/posts/2008-02-22-why-so-quiet/","section":"Posts","summary":"I have been sick for last two weeks, most of the time offline, listening to podcasts and audiobooks and doing more or less nothing. I have caught up with the backlog of episodes, saw lots of videos from Macworld.\nAmong the audiobooks I was listening two, some recommendations:\nThe Company is good parody of the corporate life. Starting with missing donut, it tells the story of a new hire in large corporation, governed by strange rules. It soon has an interesting twist - find for yourself. The book is available as MP3 CD, so you can save time ripping it to iPod.\n","title":"Why so quiet","type":"post"},{"content":"Apple released today the 10.5.2 update. After over a year and half with Mac platform (and over 2 months on Mac only work environment) I become fearless and installed update without too much worries :-). Year ago, I guess I would be quite concerned whether the Service Pack will or will not render my work notebook useless with unreparable registry ... I still remember the fun after SP2 got installed ...\nBut back to the topic. Upgrade went smooth and after 2 bangs (reboots) everything seems to work OK. Finally there is an option to \"tigerize\" the translucent menu, without add-ons and hacks. Time machine has small menu item to access preferences. The update promises WiFi improvements (tests pending). What seems not get fixed is the annoying rfc1323 TCP/IP stack setting (see here).\nSo far the only things broken is the Beta version of fantastic little utility Library books (highly recommended - it does support many libraries, including our). The error message that comes after the program start says:\n[sourcecode language='java']\nNSInvalidArgumentException\n*** -[DebugController length]: unrecognized selector sent to instance 0x2ade20\nStack trace:\n1 NSExceptionHandlerExceptionRaiser (in ExceptionHandling)\n2 objc_exception_throw (in libobjc.A.dylib)\n3 -[NSObject doesNotRecognizeSelector:] (in CoreFoundation)\n4 ___forwarding___ (in CoreFoundation)\n5 _CF_forwarding_prep_0 (in CoreFoundation)\n6 -[Parser initWithString:] (in Library Books)\n7 +[Parser parserWithString:] (in Library Books)\n8 -[Dynix booksOnHoldFormat1:] (in Library Books)\n9 -[Dynix booksOnHold] (in Library Books)\n10 -[MainController _updateLibraryBooks] (in Library Books)\n11 -[MainController _updateThread:] (in Library Books)\n12 -[NSThread main] (in Foundation)\n13 __NSThread__main__ (in Foundation)\n14 _pthread_start (in libSystem.B.dylib)\n15 thread_start (in libSystem.B.dylib)\n[/sourcecode]\nWhat helps is to roll back to version 2.5 which works just fine.\n","date":"February 11, 2008","externalUrl":null,"permalink":"/posts/2008-02-11-leopard-1052-update/","section":"Posts","summary":"Apple released today the 10.5.2 update. After over a year and half with Mac platform (and over 2 months on Mac only work environment) I become fearless and installed update without too much worries :-). Year ago, I guess I would be quite concerned whether the Service Pack will or will not render my work notebook useless with unreparable registry ... I still remember the fun after SP2 got installed ...\n","title":"Leopard 10.5.2 update","type":"post"},{"content":"After long time, I stumbled upon something that is both educational and practical. Since Doug Lea's classic, this is very readworthy work on concurrency in Java world. It focuses on Java 5 features and addresses both Web applications as well as GUI apps - each group having their own share of concurrency related problems\nHere is the Amazon page for the book - check the reviews. There is also a sample chapter available on the book's website. If you have Safari subscription, you can read it there as well.\nRecommended.\n","date":"February 6, 2008","externalUrl":null,"permalink":"/posts/2008-02-06-book-recommendation-java-concurrency-in-practice/","section":"Posts","summary":"After long time, I stumbled upon something that is both educational and practical. Since Doug Lea's classic, this is very readworthy work on concurrency in Java world. It focuses on Java 5 features and addresses both Web applications as well as GUI apps - each group having their own share of concurrency related problems\nHere is the Amazon page for the book - check the reviews. There is also a sample chapter available on the book's website. If you have Safari subscription, you can read it there as well.\n","title":"Book recommendation: Java Concurrency in Practice","type":"post"},{"content":"I am having the pleasure working with Spring 2.x since about October last year. It is my return back to Spring, after first encounter in 2005 (counting only larger projects). Same as in previous project, it has been so much fun :-). So much fun in fact, that I was spending my evening playing with code and reading up what is new in 2.5, rather that blogging ;-)\nI am still amazed about how nice is the whole thing designed and how many ways it can be used. It's flexibility is simply breathtaking. The price for the flexibility is complexity - sometimes it is not obvious what of many options should be chosen and what are all these options anyway :-).\nSpring has very good documentation, compared to most of the open source projects I have looked at (and it was pretty large number over last 10 years). There are also many books on Spring, several of them pretty good. All this makes the fairly steep learning curve more accessible. But what is still missing are good examples.\nBut wait a moment, you may say - Spring source distribution DOES have several examples - for example JPetstore (offering two alternative implementations of UI - once using Spring MVC, once using Struts), Petclinic, and several others. The source code is nicely readable and well commented. So what is the big deal ?\nThe big deal is the ratio of options and possibilities offered by the framework to the options actually presented and demonstrated by the examples. Let's take only the Spring MVC, which is certainly less than 30 % of the area covered by framework. Considering the possible combination of components would easily justify 20 examples just on that topic, not 2 or 3. The examples select one or two of possible URL mappers, provide some examples of controllers, view resolution and then the actual view. What is missing are alternatives and explanation of the differences. How would using SimpleUrlHandlerMapping instead of BeanNameUrlHandlerMapping impact the application, is explained pretty well in Chapter 13 of the documentation. For an experienced developer this (and a source code itself) is usually enough. If you try to explain Spring based application to somebody without prior IoC / DI experience, you may find out that it is not as obvious and that having an example of working code that would show the actual different implementation and letting him/her to compare and experiment, turning one into another would probably be the easiest way how to get started.\nI realize that creating enough examples could be possibly a code maintenance nightmare - at least if the pace of Spring development will remain the same. In many cases, more documentation on the samples, explaining how it works at the high level and discussing the alternatives would be almost as helpful as the full source. The otherwise very good documentation is quite brief on the Samples side - the Chapters 26 has about two screens, and that for all the samples.\nAnd because this is definitely NOT a rant, but an attempt to make a constructive suggestions, I plan to do something about the situation myself and will post the notes from \"dissecting the Spring App\" that I used for explaining how things works in Spring MVC and around. As soon as I get them to presentable form ;-). Stay tuned.\n","date":"February 4, 2008","externalUrl":null,"permalink":"/posts/2008-02-04-spring-framework-the-biggest-missing-piece/","section":"Posts","summary":"I am having the pleasure working with Spring 2.x since about October last year. It is my return back to Spring, after first encounter in 2005 (counting only larger projects). Same as in previous project, it has been so much fun :-). So much fun in fact, that I was spending my evening playing with code and reading up what is new in 2.5, rather that blogging ;-)\nI am still amazed about how nice is the whole thing designed and how many ways it can be used. It's flexibility is simply breathtaking. The price for the flexibility is complexity - sometimes it is not obvious what of many options should be chosen and what are all these options anyway :-).\n","title":"Spring Framework - the biggest missing piece","type":"post"},{"content":"This one took some time to figure out - it is one of those problems that are obvious after you know the solution but hard to see beforehand.\nI had the ResourceBundleViewResolver configured with Tiles 2, like this:\n[code language='xml']\n[/code]\nand the view.properties was:\n[code language='xml']\nparent-view.(class)=org.springframework.web.servlet.view.JstlView\nparent-view.(abstract)=true\nabout.url=/WEB-INF/jsp/about.jsp\nform.url=/WEB-INF/jsp/form.jsp\nlist.url=/WEB-INF/jsp/list.jsp\n[/code]\nIt kept givin exception saying that /WEB-INF/jsp/list.jsp does not exist. Which it did. I tried couple of things, no result.\nThe problem was in trailing space AFTER list.jsp, therefore the path to JSP file searched for was \"/WEB-INF/jsp/list.jsp \", not \"/WEB-INF/jsp/list.jsp\".\nNot sure if this is bug or feature - but removing trailing spaces should really be a sensible thing to do. As I found afterwards, the problem exists since 2005 - see this and this.\n","date":"January 24, 2008","externalUrl":null,"permalink":"/posts/2008-01-24-spring-2-mvc-and-resourcebundleviewresolver-problem/","section":"Posts","summary":"This one took some time to figure out - it is one of those problems that are obvious after you know the solution but hard to see beforehand.\nI had the ResourceBundleViewResolver configured with Tiles 2, like this:\n[code language='xml']\n[/code]\nand the view.properties was:\n[code language='xml']\nparent-view.(class)=org.springframework.web.servlet.view.JstlView\nparent-view.(abstract)=true\nabout.url=/WEB-INF/jsp/about.jsp\nform.url=/WEB-INF/jsp/form.jsp\nlist.url=/WEB-INF/jsp/list.jsp\n[/code]\nIt kept givin exception saying that /WEB-INF/jsp/list.jsp does not exist. Which it did. I tried couple of things, no result.\n","title":"Spring 2 MVC and ResourceBundleViewResolver problem","type":"post"},{"content":"I am back to Java and on mission of re-discovering Spring coolness - and in awe how much was added since 1.2 to current 2.5.1. Thanks, SpringSource and hundreds of contributors.\nData layer of the current project is based on iBatis and Spring DAO. We have decided to try out the Abator tool from Apache (part of the iBatis suite) to generate initial version of data mapping (as we inherited the database schema).\nOnly necessary part is abator.jar (there are no other dependencies).\nThe abator is driven by the XML file that defines to which database to connect and which tables must be be processed.\nRunning abator is simple:\n[sourcecode language='java']\njava -cp abator.jar org.apache.ibatis.abator.api.AbatorRunner PROJECT.xml true[/sourcecode]\nParameter 'true' defines whether generator will overwrite files.The generated files are stored in location from xml file (in our case 'generated/src'). This directory MUST exist - Abator will not create it.The project file contains information about your database driver + connection the used generator, packages for generated Java and XML files. The Java5 generator is very useful, because it produces code using generics. Abator can also understand Spring based iBatis templates and produce code directly usable in Spring projects.Two \"gotchas\" I have encounter (so far):\nIf you generate maps with many tables, the Abator assumes that you will be using namespaces. The examples from Spring do not however use namespaces, so if you use the existing code as blueprint for your project, make sure you have the namespaces enabled in the sqlmap\n[sourcecode language='java']\n...[/sourcecode]\nSecond is related to timestamp columns (e.g. CREATED_AT and similar columns).In Java, they are (most of the time) represented as java.util.Date object, which contains both date and time portion. In SQL, there are multiple data types available, depending on your database. We are using Oracle 10g and the generated map was using DATE as SQL type. This caused cutting of the time portion of the value and setting all times to 0:00:00.The solution was to use proper, explicit types for both SQL and Java. You may need to edit the map in multiple locations, replacing:\n[sourcecode language='xml']\n[/sourcecode]\nwith\n[sourcecode language='xml']\n[/sourcecode]\nand the\n[sourcecode language='xml']\nCREATE_DATE = #createDate:DATE#,\n[/sourcecode]\nwith\n[sourcecode language='xml']\nCREATE_DATE = #createDate:DATETIME#,\n[/sourcecode]\nAfter this, everything works fine.So far, the only minor unresolved annoyance is the abatorgenerated_ prefix of all SQL id's - I cannot find the way how to switch it off.It is sometimes very useful - if you want to re-run the tool, it will not touch SQL without this prefix. In our case, where the generated code is just an initial step to speed us in getting the initial codebase out fast., we would actually prefer to avoid it and keep the SQL fragments id's nice and tidy.\n","date":"January 20, 2008","externalUrl":null,"permalink":"/posts/2008-01-20-using-ibatis-with-abator/","section":"Posts","summary":"I am back to Java and on mission of re-discovering Spring coolness - and in awe how much was added since 1.2 to current 2.5.1. Thanks, SpringSource and hundreds of contributors.\nData layer of the current project is based on iBatis and Spring DAO. We have decided to try out the Abator tool from Apache (part of the iBatis suite) to generate initial version of data mapping (as we inherited the database schema).\nOnly necessary part is abator.jar (there are no other dependencies).\n","title":"Using iBatis with Abator","type":"post"},{"content":"Of course, I mean the other Steve, Steve Jobs. My world is revolving around few Steves. Steve Jobs is usually Steve Nr. 2 - and no, Joel - the Steve #1 is definitely not Ballmer :-). But every year, for two brief occasions - Macworld and WWDC - Steve Jobs becomes Steve #1 for very large amount of people.\nI was waiting with this post full day to allow the new-ity of the keynote sink in and reality distortion field to evaporate .... This is my take on the latest from Appleverse - and an answer to all who were asking whether I did already (pre)ordered and what :-). The answer is - nothing so far. I even have mixed feelings about the four Macworld news and here is why:\nBiggest news and coolest announcement is the Macbook Air. Yes, it looks very nice indeed. Yes, the new gestures are amazing. Both pricewise and performance-wise it sits in between Macbook and Macbook Pro, beating both on coolness and portability. But I think I will skip this one.\nMain reason is that number of notebooks in my house divided by number of household members is already bigger than one - even if I include the cat. Besides, I do not really need ultra portable notebook so it is hard to justify the cost. For an eBook reader it is still too big and has too short battery life. And for serious work, the screen is too small and the computing power / graphics card not a match to Macbook Pro.\nIf I did not already have a Macbook, that may have been very strong temptation. But - IMHO - being thinnest and best looking is maybe most important for superstars, but not the most important feature for a notebook. For $500 less you will get same size screen with same resolution, same graphic card, 20% faster CPU plus the DVD drive and Ethernet port. Is the form factor and iluminated screen worth six hundred dollars ? You decide. I am just not convinced that it is worth the asking price of $1899. And how the hell did Apple come to the conclusion that $1799 USD times 1.01 equals $1899 CAD ? What kind of math is that ?\nApple is generally not very nice to Canadians. Regardless of pretty much parity between the loonie and the greenback for many months, we are still paying 10-15% more for the same products as our friends in the USA. We have (officially) no iPhone - unlike Germany, France and UK . Selection offered on iTunes here and down there is so different that it is not even funny. No movie rentals for us for quite some time. It may or may not be in Apple's hands and possibly caused by legal issues around our overregulated telecom sector ... But back to the Macworld.\nThe iPhone / iTouch upgrades do not excite me at all. The iPhone upgrade is irrelevant (see above) and from the new Touch 4 apps I do not need at least three. Google Maps on iTouch cannot work anywhere as good as on iPhone. Not without phone tower triangulation capability. And density of public WiFi spots in Canada .... no comment. I guess much better will be to wait until SDK is out and third party vendors will join the market. I will happily pay for an application that will make Touch better eBook reader. But charging the $20 for the apps that otherwise identical, same retail price iPod will have for free since today, just cannot be understood otherwise than Apple likes to punish the early adopters - the most loyal fans. Second time in less that 8 months. Point taken ...\nIf you live in the USA, new Apple TV is actually a great idea. The convenience of renting without leaving the sofa can make a huge difference. Price is the about the same or better as the OnDemand rental, you have 30 days to start watching and the same 24 hrs to finish as with cable. What is IMHO killer feature is making it computer independent, but still allow transfer purchased/rented content to your Mac or PC and iPod. An ideal way how to take few movies with you for a long flight or commute. I would buy one right away - if there was a good content.\nIf the Apple TV had a DVD slot, it would be completely amazing and it would be best shot to become the only box next to TV - no more need for digital terminal and DVD player ... I will re-evaluate this one when it is clear what is the iTunes movie selection in Canada - and stick with cable and DVD until then.\nLast but not least - Time Capsule. Nice, but I already have an external harddrive for Time Machine. Whether paying twice the price of 500 GB disk is worth the convenience of not having to attach the cable to my Macbook - I am not quite sure. I am also not sure how will the wireless backup speed do compared to FireWire. Capability of backing up both Macs would not help me either because the Macbook still runs Tiger ...\nSo from all the shiny new offering, my most likely 2008 purchase is something that was announced before Macworld to avoid distracting the audience and stealing the thunder: the new Mac Pro server. Getting really well designed and well built 8 cores server with 16 GB RAM for a little more than $4000 is a great deal - and he best way how to run Windows: inside the safe boundaries of UNIX :-).\n","date":"January 16, 2008","externalUrl":null,"permalink":"/posts/2008-01-16-steves-latest/","section":"Posts","summary":"Of course, I mean the other Steve, Steve Jobs. My world is revolving around few Steves. Steve Jobs is usually Steve Nr. 2 - and no, Joel - the Steve #1 is definitely not Ballmer :-). But every year, for two brief occasions - Macworld and WWDC - Steve Jobs becomes Steve #1 for very large amount of people.\nI was waiting with this post full day to allow the new-ity of the keynote sink in and reality distortion field to evaporate .... This is my take on the latest from Appleverse - and an answer to all who were asking whether I did already (pre)ordered and what :-). The answer is - nothing so far. I even have mixed feelings about the four Macworld news and here is why:\n","title":"Steve's latest ...","type":"post"},{"content":"Continuation of this post.\nAs every TiddlyWiki, the main building block of the MGTDTW (MonkeyGTD TiddlyWiki, if you are wondering what kind of monstrous acronym is that) is a tiddler. And the only one building block because everything is a tiddler. How does this map to the GTD approach ?\nThe GTD workflow works with projects, contexts and actions. Action (or task or todo) is smallest building stone. The actions in GTD are really small actions. Every goal that requires multiple steps is a project - thus project has multiple actions. Context is an environment for executing the actions - e.g. Office, On-Line, Errands. Action can be in of the the state: \"next\" - ready to be started, waiting-for (something else needs to happen before you can start), future (something you may want to do later but not really a task right now) or done. OK, this is slightly oversimplified - for real explanation check the resources in Part I.\nEverything GTD related in MGTDTW is done using tags on tiddler and \"special tiddlers\". Because tiddlers are all there is, all your actions are tiddlers. So are all your projects and context. What makes \"action tiddler\" differrent from \"project tiddler\" is that action tiddler has tag \"Action\" and tiddler representing the project has tag \"Project\". The Wiki is smart enough to provide an easy UI to assign the tags and to create the tiddler. For example, inside the \"project tiddler\", you have links to add new next action, new waiting action, new future action. Each of this create new tiddler, tags it with \"Action\" tag as well as with appropriate action status tag.\nSome tags have graphical representation rather than verbal. Clicking on yellow start will assign/unassign the tiddler Starred tag. Starred items are quick reference list for wide variety of the usage.\nIf you read The Book, you will learn about other concepts such as reference file and ticklers. Good news is that the MGTDTW implements both. The tickler is special UI for the tiddler connected with the year-month-day - an activation date. The reference is simply a tidller tagged as Reference. Simply use subject matter tagging in addition to that to properly categorize it. But whether you tag it or not, you can always find it using fulltext search as well as see it in the timeline\nThe MGTDTW has also few extensions above the \"canonical\" Allen-ist GTD (if such thing as cannonical GTD exists at all). These extensions are Areas - something similar than projects and Realms - something even wider. By default, two realms are defined: personal and work, which pretty give an idea how they can be used: separate world or zones of responsibilities. The areas are trickier: they can be used as groups for projects (for the control freaks ;-)). The UI design of the project suggest this usage and makes it very easy. In one of the Mac programs (I believe it was Things) I have founds different explanation for area: it is kind of project that is never done - like house maintenance. MGTDTW does not directly support this semantics, because the action UI does not offer the Area, only Project. But nothing prevents you in the edit mode tag the action with the area tag. It will show properly in the Area view as the Next Action, even if it is not assigned to a project.\nMany of these concepts are actually much easier to see and experience than explain. So why not donwload the MGTDTW and play with it ?\n","date":"January 14, 2008","externalUrl":null,"permalink":"/posts/2008-01-14-the-best-gtd-tool-is-still-a-wiki-part-ii/","section":"Posts","summary":"Continuation of this post.\nAs every TiddlyWiki, the main building block of the MGTDTW (MonkeyGTD TiddlyWiki, if you are wondering what kind of monstrous acronym is that) is a tiddler. And the only one building block because everything is a tiddler. How does this map to the GTD approach ?\nThe GTD workflow works with projects, contexts and actions. Action (or task or todo) is smallest building stone. The actions in GTD are really small actions. Every goal that requires multiple steps is a project - thus project has multiple actions. Context is an environment for executing the actions - e.g. Office, On-Line, Errands. Action can be in of the the state: \"next\" - ready to be started, waiting-for (something else needs to happen before you can start), future (something you may want to do later but not really a task right now) or done. OK, this is slightly oversimplified - for real explanation check the resources in Part I.\n","title":"The best GTD tool is still a Wiki - part II","type":"post"},{"content":"Last few weeks I have been using one application on iTouch much more than before: YouTube. Within my how wireless network, I can have an access to the videos on YouTube without sitting behind the computer - for example while walking on treadmill (I recommend walking slowly) or on a sofa :-).\nVery interesting videos and actually worth the time spent on them are Google technical talks from Google channel. Few examples of videos I watched and liked:\n- Linus Torvalds talk on Git\n- Brian O'Sullivan talk on Mercurial\n- Secret History of Silicon Valey\nAll these videos are available in larger format on Google Video as well.\nI was trying to watch the instructional video's from Lynda.com on iPod touch as well. Unfortunately, that does not work. I could log on to Lynda and select the section, but instead of video, only an icon of broken movie player was displayed. It seems that iTouch Safari does not support the plugin required for the Lynda videos to function.\nSpeaking of Safari - our company has corporate subscription of Safari Books online - a huge library of almost 4000 technical books. An excellent resource ! The website is very well readable on the Touch. Especially nice feature is that after you \"pinch\" web size to enlarge it (and focus on the content area), the changing to page does not resize page back to default, but keeps the resolution. This way you can easily move around and navigate with single finger ...\nNicely done Apple / O'Reilly Media :-).\n","date":"January 11, 2008","externalUrl":null,"permalink":"/posts/2008-01-11-safari-books-online-and-lyndacom-on-ipod-touch/","section":"Posts","summary":"Last few weeks I have been using one application on iTouch much more than before: YouTube. Within my how wireless network, I can have an access to the videos on YouTube without sitting behind the computer - for example while walking on treadmill (I recommend walking slowly) or on a sofa :-).\nVery interesting videos and actually worth the time spent on them are Google technical talks from Google channel. Few examples of videos I watched and liked:\n","title":"Safari Books Online and Lynda.com on iPod Touch","type":"post"},{"content":"Thanks to Kovid Goyal, the Sony Reader's very own terrible software (iTunes wannabe) can very soon be decommissioned from my software collection. The libprs500 project, multi-platform solution written in Python works very well and allows to move data between Sony and your Mac / Linux / Windows. The UI is actually pretty decent, considering that it is not native Cocoa app:\nYou can also edit metadata, which is very important because of the limited screen space on PRS500. As added benefit, the application gives you a reader for LRF file format that allows reading unprotected LRF books on the Mac/Linux as well in addition to Windows. Here is a snapshot:\nAnd best for the end: the libprs500 can do format conversion from TXT, HTML, RTF and LIT (haleluja !) as well as PDF - as long as it does not contain too many images. Seems like Christmas arrived twice this winter - and we have still Macworld ahead :-)\nHuge thanks to Kovid who wrote this thing and to Peter who made aware of it ...\n","date":"January 7, 2008","externalUrl":null,"permalink":"/posts/2008-01-07-sony-ereader-format-lrf-viewer-for-the-mac-linux-and-windows/","section":"Posts","summary":"Thanks to Kovid Goyal, the Sony Reader's very own terrible software (iTunes wannabe) can very soon be decommissioned from my software collection. The libprs500 project, multi-platform solution written in Python works very well and allows to move data between Sony and your Mac / Linux / Windows. The UI is actually pretty decent, considering that it is not native Cocoa app:\nYou can also edit metadata, which is very important because of the limited screen space on PRS500. As added benefit, the application gives you a reader for LRF file format that allows reading unprotected LRF books on the Mac/Linux as well in addition to Windows. Here is a snapshot:\n","title":"Sony eReader format (LRF) viewer for the Mac, Linux and Windows","type":"post"},{"content":"Did you notice that there are seasons for software as well ? Similarly as with other merchandise, there are times during the year when many more people suddenly decide they need that one application X. Luckily, this trend is not as extreme as with e.g. Santa hats or carved pumpkins, which are impossible to find in stores outside of the narrow window around Christmas and Halloween (I am grateful for that :-)). In software world, the most seasonal category is tax preparation software, for obvious reasons. Taxes, like the dentist checkup are not something you will be crazy even thinking about, unless it is that time of year ....\nLess seasonal but still quite tied to the \"New Year's Resolutions' Season\" is the personal productivity software. Every year in January, big part of the population starts to work on their time management skills, weight loss, healthy eating or personal productivity in general. I personally cannot wait until this wave fades and the gyms are at normal mostly-empty state - I hate waiting in line to get to treadmill just to listen to next episode of the TWIT. But back to the software.\nAfter reading a lot (and I mean a lot) of articles about the best way how to do GTD (if you are not familiar with the cult of the GTD, see the 43 Folders, listen to the Merlin Mann's interview with David Allen or buy The Book - ideally all of these), I have decided to review my tool selection from about 2 months ago. I am informally following the GTD approach with mixed success - I am about 10% more productive, but at least 50% less stressed, which much more important.\nThe GTD tools come in three categories: online-only, desktop based and something in-between. Hardest decision was deciding between whether go online only or not. As with GMail, having all your data in the cloud is so convenient and it eliminates problems with backups and synchronization. But what makes sense for email, does not necessarily work for the task management as well: quite often you want to go offline, free from temptations of RSS newsfeeds and distraction of the Web, just to think and plan. So online-only did not work for me. I did look into and tried out some online tools - if I get to it, I may write about the experience.\nNon-web based tools give the maximal user comfort, as long as you have your notebook with you. This was a problem for me before, but since I have unified all platforms on the Macbook Pro, it became so indispensable that I hardly ever part from it, so this was less an issue. Also synchronization was not too important, for the very same reason: the notebook is portable enough to be taken with me anywhere I need. The last issue was the data format: with something so important, I was careful about keeping my data in proprietary format (more so after experiencing two occasions of Outlook PST file corruption and data loss during past 10 years).\nThe solution I have selected was Wiki-in-File, based on idea of TiddlyWiki. First - Wiki-In-A-File is Wiki system, implemented as one large HTML file, which stores both the data that is displayed in the browser as well as the code driving Wiki - in JavaScript. Unlike in case of a server based Wiki, you need neither Web server, nor the database - just open the .html file and after editing the content, save it back to disk (most W-I-A-F will create backup of the old file first).\nIn traditional Wiki's, the information is structured into pages that are interlinked. In the TiddlyWiki, the unit is a page segment, named tiddler. The actual page consists of some subset of tiddlers, that are dynamically opened, added to page or closed by JavaScript code. The result is much more dynamic and less \"webbish\" - very Ajaxian.\nTiddlyWiki offers all features that one would expect in a Wiki - such as automatic interlinking of tiddlers (pages), difference and history of a tiddler. It also has few great features that you normally find only in better products such as automatic timeline (list of tiddlers edited on a date), full text search, tagging of tiddlers and search by tags, macros. One features that is lacking is security and access rights - being a single user personal Wiki, it is not really a problem.\nThere are many flavors of TiddlyWikis out there: see this, this and this - or read the comparison. What is special on the MonkeyGTD (the one I am using) is predefined set of tags and content for the GTD specific application and also possibility of saving file both locally, or uploading it to the \"cloud\" on the tiddlyspot. The uploaded version is protected by password and can be used as emergency copy. You can also edit the online copy and save it both to local disk to the cloud. The only issue that I have found out is that it takes some management to keep track where is the latest version and whether to start with remote or local to avoid overwriting some changes.\nThis post starts to get too large, so better split it in few parts. In part II I will describe how the GTD works in MonkeyGTD. Stay tuned.\n","date":"January 6, 2008","externalUrl":null,"permalink":"/posts/2008-01-06-the-best-gtd-tool-is-still-a-wiki-part-i/","section":"Posts","summary":"Did you notice that there are seasons for software as well ? Similarly as with other merchandise, there are times during the year when many more people suddenly decide they need that one application X. Luckily, this trend is not as extreme as with e.g. Santa hats or carved pumpkins, which are impossible to find in stores outside of the narrow window around Christmas and Halloween (I am grateful for that :-)). In software world, the most seasonal category is tax preparation software, for obvious reasons. Taxes, like the dentist checkup are not something you will be crazy even thinking about, unless it is that time of year ....\n","title":"The best GTD tool is still a Wiki - part I","type":"post"},{"content":"I am experimenting in JRuby and use database in virtual machine (VMWare Fusion). This is great because you can have multiple versions of multiple databases ready without polluting the notebook. One downsize though is that IP address of the database will change between the VM restarts.\nFirst important setting in Fusion is to use the 'NAT' option rather than 'Bridged'. With NAT, you database host IP address will not follow the network. It was quite annoying to change it from 192.168.X to 192.168.Y everytime I reconnected at home from work or vice versa.\nBut even with this setting, the IP may change as you restart the VM and you will have to modify the database.yml. To keep the amount of editing minimal, here is my database.yml for the shoplet example:\n[code language='ruby']\ncommon: \u0026amp;common\nadapter: jdbc\ndriver: com.mysql.jdbc.Driver\npassword: shoplet\ndevelopment:\n\u0026lt;\u0026lt; : *common\nurl: /shoplet_dev\nusername: shoplet_dev\ntest:\n\u0026lt;\u0026lt; : *common\nurl: /shoplet_test\nusername: shoplet_test\nproduction:\n\u0026lt;\u0026lt; : *common\nurl: /shoplet_prod\nusername: shoplet_prod\n[/code]\nIt will work in Ruby as well of course - with different (non-jdbc based) adapter..\n","date":"January 3, 2008","externalUrl":null,"permalink":"/posts/2008-01-03-jruby-keeping-your-databaseyml-really-dry/","section":"Posts","summary":"I am experimenting in JRuby and use database in virtual machine (VMWare Fusion). This is great because you can have multiple versions of multiple databases ready without polluting the notebook. One downsize though is that IP address of the database will change between the VM restarts.\nFirst important setting in Fusion is to use the 'NAT' option rather than 'Bridged'. With NAT, you database host IP address will not follow the network. It was quite annoying to change it from 192.168.X to 192.168.Y everytime I reconnected at home from work or vice versa.\n","title":"JRuby - keeping your database.yml really DRY","type":"post"},{"content":"Microsoft Press is handing out 3 books:\n- Introducing Microsoft LINQ by Paolo Pialorsi and Marco Russo\n- Introducing ASP.NET Ajax by Dino Esposito\n- Introducing Microsoft Silverlight 1.0 by Laurence Moroney\nSilverlinght 1.0 is probably a bit outdated (with 1.1/2.0 close), but the others should be good, judging by the authors. Dino Esposito wrote couple of very good books on ASP.NET and .NET.\nSee this blog for more details and download links.\n","date":"January 2, 2008","externalUrl":null,"permalink":"/posts/2008-01-02-free-microsoft-press-e-books/","section":"Posts","summary":"Microsoft Press is handing out 3 books:\n- Introducing Microsoft LINQ by Paolo Pialorsi and Marco Russo\n- Introducing ASP.NET Ajax by Dino Esposito\n- Introducing Microsoft Silverlight 1.0 by Laurence Moroney\nSilverlinght 1.0 is probably a bit outdated (with 1.1/2.0 close), but the others should be good, judging by the authors. Dino Esposito wrote couple of very good books on ASP.NET and .NET.\nSee this blog for more details and download links.\n","title":"Free Microsoft Press E-Books !","type":"post"},{"content":"It is a tradition to do crazy and wild things on New Year's Eve. Some people play with fireworks and other noise making devices, other tend to celebrate the end of year by partying and drinking. I am not big fan of explosives and to sacrifice too many neurons to honor randomly chosen point on Sun's orbit sounds like a pretty silly idea. But still, I wanted to do something out-of-line on December 31st.\nSo I joined Facebook.\nIt has been nagging me for some time - the curiosity about the API's and \"Facebook applications\" and \"new platforms\" etc. The only way how to find out more and explore was to join. You can find me at firstname dot lastname at gmail dot com - if you have an account.\nThe reluctance was caused by the Facebook's demographics and motivation. Unlike some other quite geeky social networks and groups, Facebook is wide audience and general public network. It is definitely platform of the \"internet generation\" - I found there my son and many of his friends. This was very nice discovery because now I know somebody whom I can ask stupid questions without public embarrassment :-).\nPeople use Facebook to get new friends and meet new people and also expose their lives for the others. I have mixed feelings about both - I see the value of networking but .... However great it is to meet new people, if you do not have enough time for those people you already know, meeting new people makes situation only worse. And frankly - most people's life is pretty uninteresting for the others and maybe keeping private things private would be better for all.\nSo far, I am in discovery mode and try to find out what is that Facebook thing all about. I have added few friends - if you are one of them, you may be exposed to unexpected results of my experiments :-). You have been warned ...\n","date":"January 1, 2008","externalUrl":null,"permalink":"/posts/2008-01-01-facebook-time/","section":"Posts","summary":"It is a tradition to do crazy and wild things on New Year's Eve. Some people play with fireworks and other noise making devices, other tend to celebrate the end of year by partying and drinking. I am not big fan of explosives and to sacrifice too many neurons to honor randomly chosen point on Sun's orbit sounds like a pretty silly idea. But still, I wanted to do something out-of-line on December 31st.\n","title":"Face(book) time","type":"post"},{"content":"Following the book on JRuby I am discovering small differences when trying the examples. After installing activerecord-jdbc gem which is available in version 0.5, the shoplet application fails with Rails 2.0, as soon as you click on the 'About your application environment' link.\n=\u0026gt; Booting Mongrel (use \u0026#39;script/server webrick\u0026#39; to force WEBrick) =\u0026gt; Rails application starting on http://0.0.0.0:3000 =\u0026gt; Call with -d to detach =\u0026gt; Ctrl-C to shutdown server ** Starting Mongrel listening at 0.0.0.0:3000 ** Starting Rails with development environment... ** Rails loaded. ** Loading any Rails specific GemPlugins ** Signals ready. TERM =\u0026gt; stop. USR2 =\u0026gt; restart. INT =\u0026gt; stop (no restart). ** Rails signals registered. HUP =\u0026gt; reload (without restart). It might not work well. ** Mongrel 1.1.2 available at 0.0.0.0:3000 ** Use CTRL-C to stop. Processing InfoController#properties (for 127.0.0.1 at 2007-12-23 23:13:25) [GET] Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGFzaHsABjoKQHVzZWR7AA%3D%3D--9791be23205677745e457b5bf62c50eba6e3813f Parameters: {\u0026#34;controller\u0026#34;=\u0026gt;\u0026#34;rails/info\u0026#34;, \u0026#34;action\u0026#34;=\u0026gt;\u0026#34;properties\u0026#34;} Exception in thread \u0026#34;Ruby Thread11043409\u0026#34; java.lang.NoSuchMethodError: org.jruby.runtime.builtin.IRubyObject.setInstanceVariable(Ljava/lang/String;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; at JdbcAdapterInternalService.set_connection(JdbcAdapterInternalService.java:122) at JdbcAdapterInternalServiceInvoker$set_connection_FS1.call(Unknown Source) at org.jruby.runtime.callback.FastInvocationCallback.execute(FastInvocationCallback.java:55) at org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:70) at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:158) at org.jruby.runtime.CallSite$ArgumentBoxingCallSite.call(CallSite.java:103) at org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1092) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:345) at org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:626) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:293) at org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168) at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:147) at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:158) at org.jruby.runtime.CallSite$ArgumentBoxingCallSite.call(CallSite.java:76) at org.jruby.evaluator.ASTInterpreter.vcallNode(ASTInterpreter.java:1734) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:474) at org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:626) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:293) at org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1499) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:442) at org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168) I found out that there is newer version of activerecord-jdbc, which is also renamed to activerecord-jdbc-adapter. It is important to uninstall the old gem as well as install the new one, otherwise the application will not work.\n$ jruby -S gem install activerecord-jdbc-adapter Successfully installed activerecord-jdbc-adapter-0.7 1 gem installed Installing ri documentation for activerecord-jdbc-adapter-0.7... Installing RDoc documentation for activerecord-jdbc-adapter-0.7... $ jruby -S gem install activerecord-jdbcmysql-adapter Successfully installed jdbc-mysql-5.0.4 Successfully installed activerecord-jdbcmysql-adapter-0.7 2 gems installed Installing ri documentation for jdbc-mysql-5.0.4... Installing ri documentation for activerecord-jdbcmysql-adapter-0.7... Installing RDoc documentation for jdbc-mysql-5.0.4... Installing RDoc documentation for activerecord-jdbcmysql-adapter-0.7...\u0026lt;/p\u0026gt; $ jruby -S gem list activerecord\u0026lt;/p\u0026gt; *** LOCAL GEMS ***\u0026lt;/p\u0026gt; activerecord (2.0.2, 1.15.6) ActiveRecord-JDBC (0.5) activerecord-jdbc-adapter (0.7) activerecord-jdbcmysql-adapter (0.7)\u0026lt;/p\u0026gt; $ gem uninstall ActiveRecord-JDBC Successfully uninstalled ActiveRecord-JDBC-0.5 miroslav-adamys-macbook-pro:shoplet miro$ gem list ActiveRecord-JDBC\u0026lt;/p\u0026gt; *** LOCAL GEMS ***\u0026lt;/p\u0026gt; activerecord-jdbc-adapter (0.7) activerecord-jdbcmysql-adapter (0.7)\u0026lt;/p\u0026gt; After this, everything works and shoplet connects to database - as you can see from the console log.\n","date":"December 28, 2007","externalUrl":null,"permalink":"/posts/2007-12-28-jruby-trunk-issues-with-jdbc-connectivity/","section":"Posts","summary":"Following the book on JRuby I am discovering small differences when trying the examples. After installing activerecord-jdbc gem which is available in version 0.5, the shoplet application fails with Rails 2.0, as soon as you click on the 'About your application environment' link.\n=\u003e Booting Mongrel (use 'script/server webrick' to force WEBrick) =\u003e Rails application starting on http://0.0.0.0:3000 =\u003e Call with -d to detach =\u003e Ctrl-C to shutdown server ** Starting Mongrel listening at 0.0.0.0:3000 ** Starting Rails with development environment... ** Rails loaded. ** Loading any Rails specific GemPlugins ** Signals ready. TERM =\u003e stop. USR2 =\u003e restart. INT =\u003e stop (no restart). ** Rails signals registered. HUP =\u003e reload (without restart). It might not work well. ** Mongrel 1.1.2 available at 0.0.0.0:3000 ** Use CTRL-C to stop. Processing InfoController#properties (for 127.0.0.1 at 2007-12-23 23:13:25) [GET] Session ID: BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%0ASGFzaHsABjoKQHVzZWR7AA%3D%3D--9791be23205677745e457b5bf62c50eba6e3813f Parameters: {\"controller\"=\u003e\"rails/info\", \"action\"=\u003e\"properties\"} Exception in thread \"Ruby Thread11043409\" java.lang.NoSuchMethodError: org.jruby.runtime.builtin.IRubyObject.setInstanceVariable(Ljava/lang/String;Lorg/jruby/runtime/builtin/IRubyObject;)Lorg/jruby/runtime/builtin/IRubyObject; at JdbcAdapterInternalService.set_connection(JdbcAdapterInternalService.java:122) at JdbcAdapterInternalServiceInvoker$set_connection_FS1.call(Unknown Source) at org.jruby.runtime.callback.FastInvocationCallback.execute(FastInvocationCallback.java:55) at org.jruby.internal.runtime.methods.SimpleCallbackMethod.call(SimpleCallbackMethod.java:70) at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:158) at org.jruby.runtime.CallSite$ArgumentBoxingCallSite.call(CallSite.java:103) at org.jruby.evaluator.ASTInterpreter.fCallNode(ASTInterpreter.java:1092) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:345) at org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:626) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:293) at org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168) at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:147) at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:158) at org.jruby.runtime.CallSite$ArgumentBoxingCallSite.call(CallSite.java:76) at org.jruby.evaluator.ASTInterpreter.vcallNode(ASTInterpreter.java:1734) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:474) at org.jruby.evaluator.ASTInterpreter.blockNode(ASTInterpreter.java:626) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:293) at org.jruby.evaluator.ASTInterpreter.rescueNode(ASTInterpreter.java:1499) at org.jruby.evaluator.ASTInterpreter.evalInternal(ASTInterpreter.java:442) at org.jruby.evaluator.ASTInterpreter.eval(ASTInterpreter.java:168) I found out that there is newer version of activerecord-jdbc, which is also renamed to activerecord-jdbc-adapter. It is important to uninstall the old gem as well as install the new one, otherwise the application will not work.\n","title":"JRuby trunk - issues with JDBC connectivity","type":"post"},{"content":"A friend asked me this question today - and here is my take on it (slightly expanded) answer to his email :-):\nHi Shane\nI have purchased the 8 GB because I had no choice - the 16 GB versions were sold out at the Futureshop at the time, and I was too impatient to wait for two more weeks until delivered from Apple Online store :-).\nFrom usage perspective - whether 8 GB is enough really depends how much video you plan to put on. I am not watching too much video content other than YouTube via WiFi (which is streamed and does not take any space on the device), so for me 8 GB is enough. Main reason why I am not watching video is that I usually listen while walking or driving and one cannot walk very far while concentrating on the screen without bumping into something (I tried that). With driving it is even worse (I did NOT try this one ...). If you are willing to sit while watching, the image quality of the device is surprisingly good.\nI usually carry 3-5 audiobooks on it (which adds up to about 2 GB), lots of podcasts (TWIT, Macbreak, Security Now, Windows Weekly, HanselMinutes, and few Ruby podcasts) which adds up to another gig or so - as I have only few last episodes to listen to.\nIn addition to that, I carry about 4 GB is music in case I need something for the treadmill or at work for background noise canceling. It works great. So far, even the most annoying/loud voice from cubicle next to me had not have any chance to compete with Rammstein :-). I found out that keeping about 0.5 - 1 GB free is good idea - in case there is larger chunk to sync. I also use the iTouch as PDA, but even with few hundreds contacts and calendar events, the size of data is very small.\nHaving 16 GB would only allow me to have more music - I cannot really subscribe to more audio podcasts because of time limits to listen and having more than 4-5 books adds little value. Even with 16 GB version I would not be able to have ALL my music with me - so the main advantage of not having to select which music you carry with you could not be achieved anyway.\nBut of course, YMMV - and if the above sounds like rather long rationalization of the choice I have already made and cannot change, well - maybe that is not quite wrong either. But it certainly makes me feel good about my selection :-). Besides the price difference between 8 GB and 16 GB is also a thing to consider.\nFrom all the above it looks like 8 GB is sufficient and better deal than 16 GB. Right ? Well - there is a possible catch. When the new iPhone / iTouch SDK will be available (Jan/Feb 2008), it is VERY reasonable to expect that lots of new applications for iPhone/iTouch will be available soon. The most obvious choices will be an offline reader for PDF formats, mail program that will allow read and process your emails offline, News and Feeds offline readers and various forms of Google-gear like applications for various data management with disconnected mode and synchronization via iTunes/http+WiFi. All these have one in common: they will need and utilize local storage. With that in mind, maybe the additional 8 GB can be eventually very valuable and can make real difference how useful the gadget will be.\nYour question about using for couple of hours without interaction - sure, no problem. Just make long enough playlist and you never have to touch your iTouch :-). Longest time I did that was 4 hour walk back in November, with only one break to pause it while buying coffee, so that I could understand what the friendly Timmi's employee was asking.\nGood luck with your choice. But I would still listen to Steve's keynote first - 15th Jan is pretty close. Chances are there may be announced updated version of iPod for the same price - which usually causes price drop at the previous models.\n","date":"December 27, 2007","externalUrl":null,"permalink":"/posts/2007-12-27-ipod-touch-which-to-choose-8gb-or-16gb/","section":"Posts","summary":"A friend asked me this question today - and here is my take on it (slightly expanded) answer to his email :-):\nHi Shane\nI have purchased the 8 GB because I had no choice - the 16 GB versions were sold out at the Futureshop at the time, and I was too impatient to wait for two more weeks until delivered from Apple Online store :-).\nFrom usage perspective - whether 8 GB is enough really depends how much video you plan to put on. I am not watching too much video content other than YouTube via WiFi (which is streamed and does not take any space on the device), so for me 8 GB is enough. Main reason why I am not watching video is that I usually listen while walking or driving and one cannot walk very far while concentrating on the screen without bumping into something (I tried that). With driving it is even worse (I did NOT try this one ...). If you are willing to sit while watching, the image quality of the device is surprisingly good.\n","title":"iPod Touch: which to choose - 8GB or 16GB ?","type":"post"},{"content":"I bought the Ola Bini's eBook on JRuby and started to work through the examples. The installation of the Mongrel gem in JRuby (trunk revision 5341 fails with the following error code:\n``` $ jruby -S gem install -y mongrel\u003e INFO: `gem install -y` is now default and will be removed\u003e INFO: use --ignore-dependencies to install only the gems you list\u003e Building native extensions. This could take a while...\u003e extconf.rb:1:in `require': no such file to load -- mkmf (LoadError)\u003e ERROR: Error installing mongrel:\u003e ERROR: Failed to build gem native extension.[/sourcecode]\u003e This error is logged in JIRA with id JRUBY-1771Workaround (possibly applicable for other gems is to explicitly specify the plaform:\u003e [sourcecode language='ruby']\u003e $ jruby -S gem install -y mongrel --platform jruby\u003e INFO: `gem install -y` is now default and will be removed\u003e INFO: use --ignore-dependencies to install only the gems you list\u003e Successfully installed mongrel-1.1.2\u003e 1 gem installed\u003e Installing ri documentation for mongrel-1.1.2...\u003e Installing RDoc documentation for mongrel-1.1.2... ``` ","date":"December 23, 2007","externalUrl":null,"permalink":"/posts/2007-12-23-installation-of-mongrel-gem-on-jruby/","section":"Posts","summary":"I bought the Ola Bini's eBook on JRuby and started to work through the examples. The installation of the Mongrel gem in JRuby (trunk revision 5341 fails with the following error code:\n``` $ jruby -S gem install -y mongrel\u003e INFO: `gem install -y` is now default and will be removed\u003e INFO: use --ignore-dependencies to install only the gems you list\u003e Building native extensions. This could take a while...\u003e extconf.rb:1:in `require': no such file to load -- mkmf (LoadError)\u003e ERROR: Error installing mongrel:\u003e ERROR: Failed to build gem native extension.[/sourcecode]\u003e This error is logged in JIRA with id JRUBY-1771Workaround (possibly applicable for other gems is to explicitly specify the plaform:\u003e [sourcecode language='ruby']\u003e $ jruby -S gem install -y mongrel --platform jruby\u003e INFO: `gem install -y` is now default and will be removed\u003e INFO: use --ignore-dependencies to install only the gems you list\u003e Successfully installed mongrel-1.1.2\u003e 1 gem installed\u003e Installing ri documentation for mongrel-1.1.2...\u003e Installing RDoc documentation for mongrel-1.1.2... ```","title":"Installation of Mongrel gem on JRuby","type":"post"},{"content":"I was experiencing the occasional weird behaviour on downloading large files in Leopard: the download would stall, but after stopping/restarting (which can be done in Safari and iTunes), the download would continue. It was not very consistent, and I suspected the NAT router or even Rogers - some sites were occasionally having this problem, while other sites would not.\nWhile playing with JRuby over the weekend, this happened again and pretty much prevented the gem installation - because the multi-megabyte gem index would not download from http://gems.rubyforge.org/. Strangely enough, same download would work on Tiger, on Linux and on Windows using same router - which pretty much excluded router as a cause.\nI found simple fix here - big thanks to Chris D Searle. Run the following:\nsudo sysctl -w net.inet.tcp.rfc1323=0 (it replaces the default value of 1)\nI do not know all the details of the fix - it switches off some TCP window optimization which may have been the cause of the problem. More on the parameter and how to set it in variety of OS-es can be found in the TCP tuning handbook.\nTo make change permanent, create (or edit) the file /etc/sysctl.conf with the content:\n``` net.inet.tcp.rfc1323=0 ``` ","date":"December 22, 2007","externalUrl":null,"permalink":"/posts/2007-12-22-fix-for-the-stalled-downloads-in-leopard/","section":"Posts","summary":"I was experiencing the occasional weird behaviour on downloading large files in Leopard: the download would stall, but after stopping/restarting (which can be done in Safari and iTunes), the download would continue. It was not very consistent, and I suspected the NAT router or even Rogers - some sites were occasionally having this problem, while other sites would not.\nWhile playing with JRuby over the weekend, this happened again and pretty much prevented the gem installation - because the multi-megabyte gem index would not download from http://gems.rubyforge.org/. Strangely enough, same download would work on Tiger, on Linux and on Windows using same router - which pretty much excluded router as a cause.\n","title":"Fix for the stalled downloads in Leopard","type":"post"},{"content":"One of the most readable, original blogers out there, writing on software development practice and techniques - Joel Spolsky - published an excellent 3 part Talk at Yale: Part1, Part2 and Part3.\nYou will find out:\n- what two computer science courses were most useful in his university studies\n(one that was not really a comp-sci and one he decided to drop)\n- why is it tough to be an in-house programmer\n- why is the quality of many in-house systems so bad\n- what is this \"quality thing\" anyway\n- why is specification futile\nHighly recommended.\n","date":"December 20, 2007","externalUrl":null,"permalink":"/posts/2007-12-20-joels-gems/","section":"Posts","summary":"One of the most readable, original blogers out there, writing on software development practice and techniques - Joel Spolsky - published an excellent 3 part Talk at Yale: Part1, Part2 and Part3.\nYou will find out:\n- what two computer science courses were most useful in his university studies\n(one that was not really a comp-sci and one he decided to drop)\n- why is it tough to be an in-house programmer\n- why is the quality of many in-house systems so bad\n- what is this \"quality thing\" anyway\n- why is specification futile\n","title":"Joel's gems","type":"post"},{"content":"in case you have not noticed - Interface21 aka SpringSource (great name change, btw) runs a blog with lots of hidden treasures inside.\nRecent article describes new addition to Spring portfolio which is territory within my \"watched space\": enterprise integration. See the blog entry for more.\nIf you are in corporate space that is keen on \"standards\", the comparison of Spring vs EJB3 is very good article as well. Not that EJB would matter too much these days (IMHO) - but a nice read nevertheless.\nRecommended.\n","date":"December 19, 2007","externalUrl":null,"permalink":"/posts/2007-12-19-great-spring-blog/","section":"Posts","summary":"in case you have not noticed - Interface21 aka SpringSource (great name change, btw) runs a blog with lots of hidden treasures inside.\nRecent article describes new addition to Spring portfolio which is territory within my \"watched space\": enterprise integration. See the blog entry for more.\nIf you are in corporate space that is keen on \"standards\", the comparison of Spring vs EJB3 is very good article as well. Not that EJB would matter too much these days (IMHO) - but a nice read nevertheless.\n","title":"Great Spring blog","type":"post"},{"content":"The part 1 of the post is here --- continuing ---\nSo back again - different coffee shop (Starbucks at Carling), freshly charged battery, Grande Latte and no internet connection (which means no distractions from emails and the Web) - here we go again, part 2.\nIf I should single out one or two technologies that I think I have neglected and should have paid much more attention to it would be the Web trio of HTML/JavaScript/CSS as one and the SQL as second.\nLet's look at the Web trio first. It sounds weird - how can THIS be neglected, everybody knows HTML, right ? Wrong. What I mean is to have deep understanding of the HTML markup, so that you know when to use (and when not to use) tables, how to properly layout your page, fully understand the possibilities and implications of div and span, the box model and what can and cannot be done with styles and CSS. And I do not mean using Dreamweaver like tools or (god forbid) Frontpage to create the markup, I mean actually writing the markup. Ability to produce and maintain clean markup is very important for application lifecycle and evolution. Clean markup is at the beginning of every good looking site. Even if you get the first mockup version from your designer, it is up to *you* to componentize the pages, convert them to JSP or ASP.NET or RHTML (or what server side stack you are using). And it is up to you not to mess it up in the process.\nThe CSS is trickier - it is considered to be \"designer's thing\" between us, developers. And designers, they are those slightly weird artistic folks with Photoshop magic lassos and Macbooks that just somehow make things look great for no particular reason. They are so different species and us, developers who recognize 16 basic colors and do not mind using Times New Roman for everything will never be able to match their skills ... This is partially true. It is hard to learn creative design. But even if you never will, it is still important to understand ENOUGH of CSS to know what can or cannot be done with it, so that you can maintain and enhance the design of the page without messing up the styles or the markup. You would not believe how big PITA it is to go through 100+ pages just to extract hard-coded font and size references, inserted there by the previous contractor who did not know any better ... Do not do that to the guys that will maintain the app after you, it is very bad thing for your karma.\nThe HTML/CSS/JavaScript is also very important because it is the third platform, and despite JavaFX, SilverLight, Apollo and Flex flexing the muscles (pun intended) and a lot of buzz about the RIA, the traditional web technologies it is not going to go away any time soon. Listen to David H. Hansson interview for more. This stack is all you need to create Firefox extensions, new social network apps (like Facebook) and it will be important for the iPhone/iTouch and alike devices.\nJavaScript is particularly tricky: the language itself is actually great and very powerful but got very bad reputation. Partly because it makes very easy to write very bad code, but mostly because many people using it have not enough experience or programming background and produce terrible mess. Not enough good books also contributes. I mean there are many books on JavaScript, but most of them bad or mediocre. We really need to learn or re-learn JavaScript and use it the proper way. I personally would pick JavaScript against Visual Basic any time.\nThe reason that I mention SQL is because most developers know just one part of it - how to select some data, insert or update. There is another part - that deals with creating tables, indexes etc and is usually \"owned\" by the professional DBA's. Which is OK if you have one (and, btw, NEVER EVER trust a \"DBA\" that cannot create your database tables by ssh-ing to console on the server). In absence of dedicated database pros, many developers rely on GUI tools to get to initial stage of database structure, create tables, views etc. Problem in this that GUI tools cannot be version controlled and without having actual script that creates your database from scratch and loads all test data, your project environment is incomplete and you can never create good enough unit tests that will work. I have seen this to be an issue so many times that it is not even funny. Look at the migrations in Rails and how elegantly these guys solved the problem for Ruby world.\nBut enough about technologies, I'd like to add few closing more general remarks and mention some good books and sites.\nSoftware development is a discipline somewhere between engineering and creative writing (it stubbornly resists applications of engineering methods like precise estimations :-)). Same as with writing, similar path will lead you to improvement of your skills. If you want to become great writer, read a lot. Read and dissect the text, think about the storyline, plot, setup, way how the dialogs are constructed and words used. If you want to become great developer, you also need to read a lot - not only books (we will get to that), but also code. Reading good code is crucial and is very intellectually stimulating. Reading means understanding how it is designed, thinking about the relations, architecture, idioms and noting nice tricks and howtos. As with literature, the ease of reading will depend on the language (you are native Java speaker) and your preferences / predispositions. In both cases it is important to select high quality reading material. Fortunately, that is easier that it looks like as with books because there is a consensus how should good code look like. In Java world, going through the source code of Spring Framework will teach you a lot. Look at the source code repositories that do some pre-selection of the projects such as CodeHaus rather than general sites such as SourceForge. For .NET world, look at the CodeProject, select one of the highly rated contributions and chances are very high that you will be OK.\nLast but not least - few books and sites.\nOne great book that would be IMHO just right for where you are at is Refactoring from Martin Fowler. This is very easy way how get the spirit of the design patterns - IMHO better than reading the Gang of Four as the start - which is absolutely a great book to read, but maybe not the ideal to start with.\nThere few great books covering the \"craft\" of software development. The classic Pragmatic Programmer (which started the whole company) and Software Craftsmanship will give you more good advice on career of software developer than you may ever need :-). from Microsoft camp - even bigger classic is Code Complete.\nAs for sites and blogs - there are way too many blogs and feeds of interest, email me, I will send you my blog feed from Google Reader. From programmer's news I am keeping and eye on Dzone, InfoQ, TheServerside.com and theserverside.net. They may be not the best, but I found out that to actually get some time to do some coding and code reading, one must limit the news consumption ...\nThats about it.\nHappy coding, may the Source be with you ;-)\nPS: Thanks to all who managed to read until here and even bigger thanks for emails and comments to the part I. Your feedback is appreciated.\n","date":"December 14, 2007","externalUrl":null,"permalink":"/posts/2007-12-14-an-advice-to-a-fellow-developer-2/","section":"Posts","summary":"The part 1 of the post is here --- continuing ---\nSo back again - different coffee shop (Starbucks at Carling), freshly charged battery, Grande Latte and no internet connection (which means no distractions from emails and the Web) - here we go again, part 2.\nIf I should single out one or two technologies that I think I have neglected and should have paid much more attention to it would be the Web trio of HTML/JavaScript/CSS as one and the SQL as second.\n","title":"An advice to a fellow developer - 2","type":"post"},{"content":"We are recently interviewing quite a lot in anticipation of the great things coming. It is sort of similar task as we did year and something ago, but I enjoy this round much better. This time, rather than \"we have to assemble the project team ASAP\", we have the luxury of longer term view and focus more on hiring the people that will be great match to the company culture, will be with us for longer period and will grow with the company.\nWhat I really like about interviews is an opportunity talking to smart people, who are usually very interested and passionate about technology. In every one of our meetings, I like to give the candidates a good opportunity to ask questions, not only to answer them. One of questions I got few times, is \"given my resume, what technology, programming language, platform, area etc would you recommend me to look at to make progress ?\".\nI answered it, but after doing it second time, I got back to reviewing and expanding my answers. And because the \"given resume's\" were not too far apart, I decided to answer it one more time this way. So here we have, Joe Developer, a solid intermediate software engineer with good foundation and few years of Java under his belt. Joe knows the platform quite well, has done some Web application (JSP) but not too large variety of them, and also used Java in non-Web environment, e.g. GUI or some networking stuff. Joe did some scripting, a bit SQL and some basic system administration, but so far did not encounter the \"true enterprise\" technology jungle.\nSo, what should I look at, asks Joe ?\nGiven your solid Java background, build on your strength. Java may not have the sexappeal of the \"language of the week\" (which seems to be Haskell or F# or Erlang ...), but is solid, very dependable with good market penetration and it is here to stay. Making Java the center of your skillset is a good choice. If you have not look at Java 5, do it. I mean look at the NEW things available like generics, annotations, new API's for concurrency, etc.\nIn Java Enterprise space, one single most important thing happening is Spring framework. There are way too many frameworks for anything you can imagine so it is risky bet to pick one and rely on its longevity - but Spring is safe bet. Currently in version 2.5, it pretty much sums up all important trends of 2004-2007: inversion of control, aspect oriented programming, design by interface, test driven development, agile design techniques support, extending Java platform by Domain Specific Languages. It does NOT implement everything, but it provides a glue, platform that can be found everywhere. And you can find it pretty much everywhere - from Web applications to rich clients. Solid understanding of principles it represents will make your programs easier to understand, integrate, test and enhance. Spring was even influencer of Java standards - the new, radically different EJB 3 is (roughly speaking) Spring plus ORM - not that I had too high opinion about this EJB idea :-).\nIn Web application development - if you stay on Java platform - Spring has also much to offer. The Spring own MVC implementation is one of the very clean and extremely flexible approaches available for building your Web layer. Pluggable view technologies (you can mix and match the JSP/JSTL, Freemarker, Velocity, PDF), support for workflows (via Webflow), availability of security enhancements (Aecegi) makes it worthy exploring.\nBut what else than Java ? There are so many other languages - which are worth the time investment ? My take on this that you should not learn a new language that does not change your views about programming. Unless, of course you have very convincing reason to do so - like having is a long term project with dare need of this skill - this is how I learned VBA back in 1993.\nThere is a lot of \"software enlightement\" value to be found in exotic languages, that are often impractical and unsuitable for commercial skill marketplace, such as Lisp, Smalltalk or Prolog. Lot of fun and little money. Good middle ground between educational value, beauty and commercial usability is Ruby. It is real fun to use, gives you power of Perl (without the cryptic syntax), elegance of Python (with added cleanness and consistency). Ruby is also available in JVM implementation (JRuby) and offers an inroad to something really novel and interesting - Rails.\nFrom this point of view, mastering \"the other platform\" (.NET) will not teach you too much. The C# 2.0 is so close to Java that learning it for experienced Java programmer is a no-issue (of course, mastering libraries and frameworks available is completely different story). The really new additions into Windows development toolkit with .NET framework 3.x are features as LINQ (in many areas - SQL, XML) and WPF (as replacement for Winforms ??). Certainly interesting, but they are often \"me too\" solutions than something really new. They are not bad, if your projects bind you to .NET platform, they are certainly worth of learning - but IMHO the real fun is elsewhere.\nUnfortunately, one cannot avoid the feeling that not too much innovation is coming from Redmond in last couple of years - just check Zune vs iPod, Vista vs OS-x, Windows Live vs. Google offering etc. On the positive side, there is strong market demand for Windows based solutions, from Enterprise point of view, their server products are often better than their reputation. SQL Server 2005 has great price/performance ratio and is generally very good database server, development environments (VS 2005/2008) and comparable and close to what the Java world has (Eclipse, Idea, Netbeans).\nIn Web development on Windows - aka ASP.NET - an experienced Java developer will feel both surprised (by very rich controls offering) and limited (by not so great pagecentric postback-based navigational model and lack of usable MVC implementation). Compared to richness of Web framework implementations in Java, this is very sobering experience. Currently, even Microsoft seems to feel the need to address this - see Scott Guthrie and first Beta versions of true Model-View-Controller for ASP.NET. It's about time ...\nWhat you need to be aware of is that in long term, Microsoft loves to do these right-angle-technology-turns (RATTs) that will invalidate your investment into mastering particular technology. I learned it the hard way - none of the expertise in MFC and C++, ATL or COM/DCOM has too much market value today. As Joel On Software outlines, I am not alone (read more here). And I have the nagging feeling that maybe transition from Winforms to WPF may be yet another RATT. But I may be wrong, I have not really spent enough time in WPF (unlike in Winforms). To sum it up - from opportunities perspective, Microsoft technologies are good investment and tradeoff for pretty much guarantee of more opportunities coupled with (usually) less fun.\nBoth Java and C# are language of similar \"altitude\" or expressive power. Quite often trying to rise your altitude and work with very high level language is quite eye-opening experience. There are many scripting languages out there, I would pick two. First is (obviously) already mentioned Ruby. If you want to stay closer to Java integration, look at Groovy - an in-JVM high level scripting language, with not as pretty syntax, but easier to intermix with Java - although as we know, beauty is in the eye of the beholder. Besides, the Groovy folks seem to be copying implementing ruby-esque features like crazy, including the killer app, which is in Groovy named Grails :-).\nHmm, looking back, this post is getting pretty long and battery in my MacbookPro is running low (I am typing this in Zavida Coffee which has free WiFi but only few tables where you can plugin your power supply. I guess I finish it tomorrow.\n-- to be continued --\n","date":"December 12, 2007","externalUrl":null,"permalink":"/posts/2007-12-12-an-advice-to-a-fellow-developer-1/","section":"Posts","summary":"We are recently interviewing quite a lot in anticipation of the great things coming. It is sort of similar task as we did year and something ago, but I enjoy this round much better. This time, rather than \"we have to assemble the project team ASAP\", we have the luxury of longer term view and focus more on hiring the people that will be great match to the company culture, will be with us for longer period and will grow with the company.\n","title":"An advice to a fellow developer - 1","type":"post"},{"content":"If the world of physical objects would governed with the same rules as the Digital Millennium Copyright Act does impose on all things digital, scissors would be illegal and you could end up in jail for manufacturing, and maybe even owning or using them. Crazy ? Well, see this presentation and judge for yourself.\nThis \"law\" is currently impacting our friends south of the border only, but it is very real that it will soon become a law in Canada as well.\nIf you think that DMCA is a bad idea, here is couple of things you CAN do about it.\n","date":"December 11, 2007","externalUrl":null,"permalink":"/posts/2007-12-11-absurdity-of-the-dmca/","section":"Posts","summary":"If the world of physical objects would governed with the same rules as the Digital Millennium Copyright Act does impose on all things digital, scissors would be illegal and you could end up in jail for manufacturing, and maybe even owning or using them. Crazy ? Well, see this presentation and judge for yourself.\nThis \"law\" is currently impacting our friends south of the border only, but it is very real that it will soon become a law in Canada as well.\n","title":"Absurdity of the DMCA","type":"post"},{"content":"The CHM files (Microsoft compiled HTML help files) are often used for eBooks. They are readable on OS-X using excellent open source CHMOX application. If you want to get more useful preview in OuickView than the not very helpfull static icon, get this plugin.\nDownload here\nhttps://sourceforge.net/project/showfiles.p...group_id=211847\nHow to install it: Unzip it, take the proper package for your system (the ZIP file contains several architectures, on modern Intel-based Mac's you want to use x64), put it inside\n/System/Library/Quicklook\nand enjoy !\nBig thanks to the developer Qian Qian - whoever that is.\n","date":"December 10, 2007","externalUrl":null,"permalink":"/posts/2007-12-10-how-to-show-preview-for-chm-file-in-leopard/","section":"Posts","summary":"The CHM files (Microsoft compiled HTML help files) are often used for eBooks. They are readable on OS-X using excellent open source CHMOX application. If you want to get more useful preview in OuickView than the not very helpfull static icon, get this plugin.\nDownload here\nhttps://sourceforge.net/project/showfiles.p...group_id=211847\nHow to install it: Unzip it, take the proper package for your system (the ZIP file contains several architectures, on modern Intel-based Mac's you want to use x64), put it inside\n","title":"How to show preview for CHM file in Leopard","type":"post"},{"content":"One of the languages that I managed to completely ignore for almost 20 years was Objective-C. I always saw it as less developed, dead-end version of C++ that has little perspective - despite that GCC supported it since early days. I guess I was wrong on two of three counts - that of little perspective still holds as long as you want to stay outside of OS-X platform.\nOne of the issues I had was strange syntax and that from not too many books on subject, they were\na) too hard to read because they attempted to explain Cocoa / Carbon frameworks AND the language at the same time and\nb) that they were focused on beginner audience and basically went too basic into the OOP principles and fairly obvious (for experienced programmer) stuff.\nWhat I always really wanted was detailed comparison how are things different to Java or C++. And I managed to finally find it. The good guy named Pierre Chatelier wrote exactly that. The document is over 50 pages long, has just right mixture of details and is available in English and French from here. The target audience is experienced C++ programmer, but to my pleasant surprise - even if my C++ is a bit rusty (did not do any serious coding in C++ for over 8 years) - it was perfectly understandable. I guess C/C++ is like riding a bike - once you learn it, you have it forever :-).\nThe point of actually looking at Objective-C is simple: you should not learn a new programming language that does not change the way how you look at programming or program design. And Objective-C seems to be very good candidate to deliver that. The strange syntax (borrowed from Smalltalk) is actually quite simple after you overcome mental blocks inherited from UML (that + and - do indicate public/protected) and Java/C++/C# (that \u0026lt;Something\u0026gt; is related to generics/templates). The language is surprisingly powerful and I am quite enjoying reading about it. I think you will be seeing more of it on this blog ...\n","date":"December 9, 2007","externalUrl":null,"permalink":"/posts/2007-12-09-excellent-comparison-of-c-and-objective-c/","section":"Posts","summary":"One of the languages that I managed to completely ignore for almost 20 years was Objective-C. I always saw it as less developed, dead-end version of C++ that has little perspective - despite that GCC supported it since early days. I guess I was wrong on two of three counts - that of little perspective still holds as long as you want to stay outside of OS-X platform.\nOne of the issues I had was strange syntax and that from not too many books on subject, they were\n","title":"Excellent comparison of C++ and Objective-C","type":"post"},{"content":"I was trying to set up an Oracle appliance - install the Oracle Express XE into a virtual machine. What (in my mind) should be smooth and straightforward process was something very different. I should have been forewarned warned after seeing the discussion ... To make long story short, the installer failed on three different Linux VM's I had available - because of unavailable dependencies, too small swap space etc, etc.\nI am not picking neither on Linux nor on Oracle as there is no such thing as standard or predictable Linux installation. Even within single distribution (like Fedora 7) it is completely up to the user which subset of 1500+ packages will get selected during initial install. The installers are sophisticated enough to add missing dependencies, but nothing will prevent you not to install some seemingly unimportant package, without which the Oracle will not run. Given enough time, you can go and add the missing dependency (and it's dependency and so on - up to the transitive closure of all missing libs), but that makes the 30 minutes installation more like 3 hours project.\nWhat I ended up doing is loading the XP VM and the Oracle was up and running in less than 15 minutes. The Windows configuration is given (no user meddling possible) and the MSI installers do great job. The price to pay is the nagging feeling that each install may bring that huge binary blob called registry closer to it's death ... but in VM's that is a non-issue.\nThere are two ways how to avoid issues like this. The option is go for pre-configured virtual appliance. Lots of appliances are available for VMWARE or for Microsoft Virtual Server.\nIf there is no appliance, next best thing is to go for \"stack install\". Many software packages are now available bundled as stacks - e.g. LAMP/MAMP/WAMP stack (Apache with PHP and MySQL on Linux, Mac or Windows). There is good website BitNami offering many more stacks, including Liferay portal, Alfresco, Joomla, Drupal, Wordpress or Ruby stack ... This in combination with an \"empty\" VM should really ease the pain.\n","date":"December 8, 2007","externalUrl":null,"permalink":"/posts/2007-12-08-taking-the-pain-off-installation/","section":"Posts","summary":"I was trying to set up an Oracle appliance - install the Oracle Express XE into a virtual machine. What (in my mind) should be smooth and straightforward process was something very different. I should have been forewarned warned after seeing the discussion ... To make long story short, the installer failed on three different Linux VM's I had available - because of unavailable dependencies, too small swap space etc, etc.\n","title":"Taking the pain off installation","type":"post"},{"content":"As long as you are using OS-X, this is something worthy looking at: the MuPromo is running the annual bundle offer with (currently) 8 applications, worth $534 for the mentioned $49.99. The sale is on for 4 more days. The way how it works is that at certain marks, additional applications will be added to the bundle (for the same price) and will be made available to everybody who purchased the bundle. Including me :-). Currently, the sales are at \u0026gt; 1600, the next app will be added at 2400 (pretty sure it will happen) and the last one at 5000 (fairly likely).\nWhat got me interested were 3 applications:\n1) ForkLift - a TotalCommander like file manager, fulfilling my obsession with two windows side-by-side. It is not as powerful as the TotalCommander or Krusader (on Linux), but it does allow going into ZIP files as if there were part of file system and it also does the FTP/SFTP connectivity.\n2) Yep - it is kind of \"iTunes for PDF\", an organizer that can tag, sort and manage large amount of PDF files. For example eBooks :-). The same company offers the Beta of Leap - and boy, that looks *really* great !\n3) XMIND - mind mapper. An Eclipse RCP based app to do the brainstorming, mind mapping and diagramming. Being Eclipse/Java based, it will run on Linux or Windows as well (I think the license even allows it - but I do not really care, as I will run it on Mac only). On the negative side, being Eclipse based it does not quite look and feel as the proper Cocoa app - but it is quite OK. This is most pricey piece, selling for $299 (with Intro price $129.99 until December 31st) - so this alone is worth the bundle.\nDisclaimer #1: As I did already purchase the bundle, I have obviously vested interest in getting more people do the same :-)\nDisclaimer #2: Despite of disclaimer #1, I do not really need or care for #9 or #10, as I already got more that my money's worth in ForkLift, Yep and XMind. Therefore my recommendation is really based on my belief that this is a great deal.\n","date":"December 7, 2007","externalUrl":null,"permalink":"/posts/2007-12-07-over-500-worth-of-software-for-4999/","section":"Posts","summary":"As long as you are using OS-X, this is something worthy looking at: the MuPromo is running the annual bundle offer with (currently) 8 applications, worth $534 for the mentioned $49.99. The sale is on for 4 more days. The way how it works is that at certain marks, additional applications will be added to the bundle (for the same price) and will be made available to everybody who purchased the bundle. Including me :-). Currently, the sales are at \u003e 1600, the next app will be added at 2400 (pretty sure it will happen) and the last one at 5000 (fairly likely).\n","title":"Over $500 worth of software for $49.99","type":"post"},{"content":"Did you know that for the price of two movie tickets you can spend the full month watching interesting stuff that matters ? This is true, as long as\na) your definition of of \"interesting stuff that matters\" is a bit on the nerd site of a spectrum\nb) you do not get full package with your movie ticket - I mean popcorn + soda - just the ticket.\nIf you do go for popcorn, we should say \"for the price of 1.2 movie ticket\", because the amount we talk here about is $25 USD, which still is almost the same amount in loonies. As for the case a), do you find that an example of interesting stuff that matters is video tutorials about development in Ruby on Rails (22 hours), advanced techniques in Photoshop or even Silverlight essentials ? If yes, look at the Lynda movie library. It is subscription based service that offers over 2'000 tutorials on wide variety of all things digital, covering both deeper, developer level areas as well as more general user topics.\nThe videos must be watched on-line (no downloads are available, just the stream), but the streaming is very smooth and image quality is very acceptable. Most of the tutorials are screencasts with voice-over, some are combination of slides and demos. The lessons are cut into reasonably short (3-15 minutes) pieces, which fits well into busy schedule. To have an idea about the quality of the stuff, many tutorials have few free few chapters - check them out.\nIf you prefer to pay as you go and want deeper, very ruby-esque and rails-ish topic, look at the Peepcode. I do not like the name - but the content is good, screencasts done by the guys who know what they are talking about. The single \"show\" (about an hour long, give or take) costs $9 for single download, or in packs of 5 ($40) and 10 ($70). Unlike the Lynda, these screencasts can be downloaded and as nice surprise, the downloads are reqular Quicktime movies, without the DRM nonsense. Recomended.\nAnd speaking of evil things like DRM, you may not be aware that something unpleasant is possibly going to happen in that great country of ours: Canadian version of DMCA. Look at this, this and this and if you care, join the crowds - or at least, help spread the word.\n","date":"December 6, 2007","externalUrl":null,"permalink":"/posts/2007-12-06-movie-theatre-for-us-geeks/","section":"Posts","summary":"Did you know that for the price of two movie tickets you can spend the full month watching interesting stuff that matters ? This is true, as long as\na) your definition of of \"interesting stuff that matters\" is a bit on the nerd site of a spectrum\nb) you do not get full package with your movie ticket - I mean popcorn + soda - just the ticket.\nIf you do go for popcorn, we should say \"for the price of 1.2 movie ticket\", because the amount we talk here about is $25 USD, which still is almost the same amount in loonies. As for the case a), do you find that an example of interesting stuff that matters is video tutorials about development in Ruby on Rails (22 hours), advanced techniques in Photoshop or even Silverlight essentials ? If yes, look at the Lynda movie library. It is subscription based service that offers over 2'000 tutorials on wide variety of all things digital, covering both deeper, developer level areas as well as more general user topics.\n","title":"Movie theatre for us, geeks","type":"post"},{"content":"Today I got to trying out the major feature of Leopard: the Time Machine. I was postponing it because I did not have proper external storage. Although I do have several USB disks sized from 100 to 260 GB, they are not empty and to clean them would take too much time that I currently do not have. Backing up on network drive would be technically possible - with some tweaking - but copying over network is always slower than USB2 or FireWire. Besides, the drives are so cheap nowadays: I have picked the 500 GB \"The Book\", Western Digital in Costco (Kanata) for $149. You have to agree that one cannot resist this price and product with this name (I have a weak spot for anything Book ;-))\nTime machine requires drive at least as big as the machine hard disk - which is at least 250 GB in my case. But if the whole point of time machine is to keep HISTORY of files, therefore (unless your disk is mostly empty) the only way how to do it is make the backup drive bigger. Double the size is a good start. I have asked the Apple guys what would happen when the backup drive gets full and it seems to be pretty nicely designed: when the backup space is tight, Time Machine starts purging older versions and your window back in time starts shrinking, up the point (in worst case) having a single last backup. I have not seen it yet, but it makes sense - worst case scenario is the \"default\" backup algorithm.\nThe Apple guys also mentioned that you can add additional drive and Time Machine should be able to use them together - sort of expanding the backup to new volume - as long as the are plugged in at the same time. I was expecting that after (e.g. year from now) I buy a 1 TB drive, I would need to copy the content of the old 500GB and have the new backup capacity equal to 1 TB in total, but this seems not to be case. Actually, copying is something you should NOT do - just make sure both disks are plugged in and Time Machine will manage the rest - and (assumably) if you do it soon enough, with 500 GB and 1 TB disk you will get 1.5 TB space. Well, with three USB 2 and two FW ports, I guess I can go for VERY long span back in time :-) - as long as I keep buying more USB/FW disks. If this idea takes off and Microsoft does copy this feature from OS-X as well (as they did for many others), buying stock of external hard drives manufacturers may be a good investment :-).\nTime machine can be configured not to backup certain files. This makes sense for e.g. VMWare virtual hard disk image, which gets modified pretty much after each run and each backup would copy whole file - few gigabytes worth. For VM, the best strategy is to have different external hard drive (ideally formatted as FAT32 so that it can be read/written on Linux and Windows as well) and use to for VM copies only. Which is exactly what I am going to do next.\nThe disk is being backed up as I type this. Drive is very quiet, almost unnoticeable, even with fan inside (you can feel the air moving). Backing up 160 GB (yes, I managed to fill so much space) will take an hour or two, so we will see how the restore works tomorrow.\n","date":"December 4, 2007","externalUrl":null,"permalink":"/posts/2007-12-04-trying-out-the-time-machine/","section":"Posts","summary":"Today I got to trying out the major feature of Leopard: the Time Machine. I was postponing it because I did not have proper external storage. Although I do have several USB disks sized from 100 to 260 GB, they are not empty and to clean them would take too much time that I currently do not have. Backing up on network drive would be technically possible - with some tweaking - but copying over network is always slower than USB2 or FireWire. Besides, the drives are so cheap nowadays: I have picked the 500 GB \"The Book\", Western Digital in Costco (Kanata) for $149. You have to agree that one cannot resist this price and product with this name (I have a weak spot for anything Book ;-))\n","title":"Trying out the Time Machine","type":"post"},{"content":"Why did I arrive to this conclusion so sudden ? After all, I have the iPod for over a month and half now and never really used it for anything beyond podcasts/music/videocasts.\nThe answer is simple: 1.1.2. The Firmware update that appeared during last sync upgraded the iPod to latest version which (in addition to obligatory bug fixes) brought the long needed possibility of adding an event or modifying an event in calendar or adding/modifying an address card.\nWith this in place, I can finally use iPod as the PDA - because you will get information about some new address or phone number change most likely when you are not at the computer or online and without this feature, there would no way how to capture it. I tried to use pen and paper - but it is so easy to loose the paper or forget to enter it ...\nBecause all of my calendar data are living in Google cloud, I needed a way how to sync iCal data from my Mac with Google. There are at least 4 different ways how to do that:\n1) SpanningSync - the subscribtion based product\n2) gSync - very affordable program from Macness.com\n3) OpenSource Java based GCalDaemon - very interesting but with fairly lengthy setup\n4) using free Plaxo pluging for address book\nI was looking into SpanningSync before and even evaluated it, but I think the value of the service is not worth of $25 a year. I would not mind to buy the application for that price, but for paying every year it is too much. Besides, SpanningSync runs your data using third party server, which is another issue - you pay twice: on top of dollars, by giving up control over your data.\nThe gCal offers much better price/performance ratio - for one time fee of 10 pounds you can use it as long as you wish - or as long as Google does not modify their API. I cannot comment on it's functionality, because I ended up using the #4 solution.\nI have been using Plaxo already for over a year to keep address books between different platforms in sync. It was then the only practical solution how to synchronize Thunderbird contacts, Address book on Mac, Outlook contacts and Yahoo. Now it can in addition to synchronizing address books also synchronize the calendars and added the Google as data source. The contacts synchronization is one-way only (you can load your contacts from GMail to Plaxo), but calendars are synchronized both ways without any issues. Plaxo basic service is still free, if you want premium you can get de-duplication option and synchronization with LinkedIn. Unfortunately - same as with SpanningSync - the value of the service for me is not as high as their price. YMMV.\nI have downloaded the addresses from Plaxo, synced them iPod and tested that you really can edit or add an appointment in your iPod and that with the next sync it makes it up to the cloud and shows in your Google Calendar. And vice versa. If you are online, the updates in address book or iCal are synced almost immediately to Plaxo and with short delay to Google.\nFew recommendations: after adding Google sync point and setting up the link, do one synchronization and then switch the contact synchronization off (keeping the calendar sync only). Why ? Because your Google contacts contain most likely just a names and emails or even emails only as Google extracts them from the emails arrived. After sync, you will want to clean up and consolidate your data by assigning the newly collected emails to people in your address book and deleting the incomplete records. Without switching the contacts synchronization off, you will have them back and can start the deleting again :-) - as I learned the hard way.\nIt is also important to understand to which calendar are the newly created appointments from iPod added - especially when your settings in GCal and iCal do not 100% match.\nNow back to the subject: why is this the best PDA ? I was using several Palm based devices as well as Windows Mobile based PDA's (one of them - the Toshiba e830 is still being used as eBook reader) and every one could synchronize the appointments and addresses. The largest difference is the Touch user interface - you have to try it to understand. None stylus based Palm or PocketPC came ever close to the simplicity and functionality of the Touch. Not speaking about the beauty of the UI, of course.\nSecond reason for being the best is the tool chain behind the iPod. Syncing using iTunes and Mac / iCal / Address book is by order of magnitude better user experience that using ActiveSync and Outlook. True, using Plaxo you could move the data from iPaq to Google same way - or maybe the new Outlook is even Google aware - I have no idea because I stopped using Outlook in 2005.\nAnd last but not least reason is that NONE of my previous PDA's could serve as iPod, show images or video or even surf a Web via WiFi. I stopped using WiFi on Toshiba PocketPC after it was obvious that for 99% sites the pocket version of Internet Explorer is simply unusable. I stopped trying to use it as music player because to play a song you had to use stylus and both hands. And the music stopped when you switched the device off, so instead of enjoying the podcast I was fiddling around with screen light settings to get at least few hours out the batteries.\nNow if the iPod had at least small (1-2 MPix) camera, it would be almost perfect ... but for that I guess you need to get an iPhone.\n","date":"November 30, 2007","externalUrl":null,"permalink":"/posts/2007-11-30-ipod-touch-the-best-pda-i-ever-had/","section":"Posts","summary":"Why did I arrive to this conclusion so sudden ? After all, I have the iPod for over a month and half now and never really used it for anything beyond podcasts/music/videocasts.\nThe answer is simple: 1.1.2. The Firmware update that appeared during last sync upgraded the iPod to latest version which (in addition to obligatory bug fixes) brought the long needed possibility of adding an event or modifying an event in calendar or adding/modifying an address card.\n","title":"iPod Touch: the best PDA I ever had","type":"post"},{"content":"As time passes, I am discovering more little features that either fill in the still existing gaps from my Windows toolchain or add new features. Today, at Apple presentation about Leopard Client and Leopard Server I have heard great tip.\nThe QuickView in Leopard is extensible with plugins. One very obvious and very useful plugin is ZIP View that gives you content of the ZIP file in preview without unzipping it. This is finally a workable replacement for Ctrl-PgDn of TotalCommander that allowed to \"walk into\" archive and treat ZIP file as part of the file system.\nThe plugin is free and can be found at the developer's site. The same author also wrote a Folder view plugin which replaces the mostly useless large icon with preview with icon and list of the files. His blog is mostly in Japanese, so it is hard to say what other treasures are there :-).\nInstallation is very simple: just copy the .qlgenerator files to your ~/Library/QuickLook (or to /Library/QuickLook if you want to install them for all users).\nThe server presentation was really interesting, I will get back to it in other blogpost.\n","date":"November 28, 2007","externalUrl":null,"permalink":"/posts/2007-11-28-how-to-show-zip-file-content-in-quickview-leopard/","section":"Posts","summary":"As time passes, I am discovering more little features that either fill in the still existing gaps from my Windows toolchain or add new features. Today, at Apple presentation about Leopard Client and Leopard Server I have heard great tip.\nThe QuickView in Leopard is extensible with plugins. One very obvious and very useful plugin is ZIP View that gives you content of the ZIP file in preview without unzipping it. This is finally a workable replacement for Ctrl-PgDn of TotalCommander that allowed to \"walk into\" archive and treat ZIP file as part of the file system.\n","title":"How to show ZIP file content in QuickView (Leopard)","type":"post"},{"content":"no, not because of the memory it takes or CPU cycles burned (does not really matter when you have 4 GB notebook with Core2Duo).\nFew days ago, a good friend from old country (well, technically not anymore as he also moved within the EU) made me aware of this presentation \"Silver Needle in the Skype\" (link points to fairly large PDF file) by Philippe Biondi, \u0026amp; Fabrice Desclaux.\nTo fully digest and fully comprehend the content requires way more time than I am willing to invest - and to make meaningful arguments for or against conclusions does require much deeper special knowledge. It is interesting view into the deep internals of how Skype works and also provides very interesting references to tools available for this kind of exploration. I am not going to stop using Skype just because there is a chance that Skype could possibly be a backdoor or something not so innocent. There can be after all perfectly honest reason for all the obfuscation and anti-disassembling measures - to protect the IP against competition. Or it can be in order to hide something else ? We will probably never know.\nBut I am not letting Skype start as the machine boots anymore and shut it down after I am done with my call. In other words, you will not find me online on Skype very often :-).\n","date":"November 25, 2007","externalUrl":null,"permalink":"/posts/2007-11-25-why-it-is-probably-bad-idea-to-have-skype-always-on/","section":"Posts","summary":"no, not because of the memory it takes or CPU cycles burned (does not really matter when you have 4 GB notebook with Core2Duo).\nFew days ago, a good friend from old country (well, technically not anymore as he also moved within the EU) made me aware of this presentation \"Silver Needle in the Skype\" (link points to fairly large PDF file) by Philippe Biondi, \u0026 Fabrice Desclaux.\nTo fully digest and fully comprehend the content requires way more time than I am willing to invest - and to make meaningful arguments for or against conclusions does require much deeper special knowledge. It is interesting view into the deep internals of how Skype works and also provides very interesting references to tools available for this kind of exploration. I am not going to stop using Skype just because there is a chance that Skype could possibly be a backdoor or something not so innocent. There can be after all perfectly honest reason for all the obfuscation and anti-disassembling measures - to protect the IP against competition. Or it can be in order to hide something else ? We will probably never know.\n","title":"Why it is probably bad idea to have Skype always on","type":"post"},{"content":"Today I picked the printer I have mentioned yesterday - Xerox Phaser 6120N. It is somehow more bulky than the ML-4500, but boy, does it work !! From all available connection options (parallel port, USB, ethernet) I have of course chosen ethernet. Printer after switch on spent about 5 minutes doing strange and weird noises, initializing itself and then spit out a page with its DHCP-acquired network address.\nTo assign different IP address (so that it does not change) was very easy: go to http://192.168.x.x/ - whatever is printed on the status page and follow the Web instructions under 'Network'. Set new IP, disable the automatic IP settings, wait for printer reset (and new status page) and you can go on setting the clients.\nWindows installation is very smooth - drivers are on the CD - and does not even need a reboot. As a nice surprise, the CD also contained PPD files so that now I have the printer accessible from CUPS on Linux as well. And as usual, Mac installation was pretty non-existent. The printer does not support Bonjour, but somehow both Mac's found it using AppleTalk - yet another thing I know not enough about and need to look up. So finally, all computers around my house can print reliably, in color without going through the hoops. Hooray !\nThe most amazing surprise was when I tried to print a photo. I have done it before and generally, laser printer comes nowhere even close to what you can get out of the photo inkjet - especially with proper paper. Now here I could not believe how good was the result: on plain paper, without any special calibration or color magic, the picture looked very close to an inkjet output - only waterproof.\nThis source is certainly not impartial, but anyway shows difference in fine details of output. I am no expert, but the printouts look certainly very good to me!\nDisadvantages ? Beside the size, the printer is a bit noisier than ML-4500 when it prints. Other than that, none other issues found yet.\n","date":"November 23, 2007","externalUrl":null,"permalink":"/posts/2007-11-23-phaser-6120n-rocks/","section":"Posts","summary":"Today I picked the printer I have mentioned yesterday - Xerox Phaser 6120N. It is somehow more bulky than the ML-4500, but boy, does it work !! From all available connection options (parallel port, USB, ethernet) I have of course chosen ethernet. Printer after switch on spent about 5 minutes doing strange and weird noises, initializing itself and then spit out a page with its DHCP-acquired network address.\nTo assign different IP address (so that it does not change) was very easy: go to http://192.168.x.x/ - whatever is printed on the status page and follow the Web instructions under 'Network'. Set new IP, disable the automatic IP settings, wait for printer reset (and new status page) and you can go on setting the clients.\n","title":"Phaser 6120N rocks !","type":"post"},{"content":"I have been running the Unix only workstations for over a week now. During this week, I have managed to clean up and convert two Windows boxes to VMWARE virtual machines, but actually had to resort to use the VM's only in two cases. Everything else worked just fine.\nThe first case was requirement to review an non-trivial Excel file. Normally, Numbers does very decent job when it comes to loading Excel files and for the most the remaining cases, the OpenOffice (in it's more polished Cocoa version NeoOffice) works just fine. Well - as long as you do not open spreadsheet with pivot tables. In my case, the spreadsheet contained pivot tables and charts based on these tables. Numbers warned during import that this feature is not supported and the converted spreadsheet was very good looking - nicer that in Excel, but not quite so functional :-). Strangely enough, the charts were imported OK but lost the drill-down capabilities. After trying out the NeoOffice, the imported spreadsheet had retained some pivot capabilities of the original, but lost charts completely. The only resort was falling back to Office 2003 in virtual machine and using Excel. Fortunately one of the two VM's created from old hardware had Office 2003 installed, so that worked out OK.\nThe other case of \"works only with Windows\" was the Active X control used by our VPN to get access to internal network. There is no alternative, so to get to our internal Wiki, JIRA or timesheet system, I have to start Windows in VM.\nThe last issue encountered has not really anything to do with platform change, but it was triggered by this, so here it goes. Back in 2002 I purchased very small and handy laser printer Samsung ML-4500. It worked well for all those years, happily attached to my Windows desktop machine which (being always on) shared it for everybody in home network. Of course, up to the point when that desktop machine was decommissioned. Because ML-4500 is parallel port only printer, has no USB, first issue was to find a machine that actually still has a parallel port (most of new machines do not). By lucky coincidence, my NAS Linux system had parallel port - so I dived into new adventure of configuring CUPS printing system under Linux and sharing the printer via Samba. Which was much easier that it may seem - hats off to Linux hackers. The ML-4500 was part of the CUPS printer's database and was recognized right away. Only small hickup was disabled parallel port in BIOS - but after this got corrected, things worked OK (thanks to Peter for the hint).\nSo now I can print from Linux, can even share the printer but still cannot print from Windows or Mac. Why so ? If you try to attach the printer from Windows machine, Windows wants to install driver. The ML-4500 is not in the default driver database. I still have the original CD from Samsung, but attempt to install driver fails with completely useless error message. Updated driver is nowhere to be found. I do not remember how I did install the driver back in 2002, but nevertheless, the machine is gone. Even if I do have the driver inside VM, I do not have VMWARE installed on Linux (and do not plan to do so). So for now, only way how to print from Windows notebooks (or Macs) is to create a PDF file on the client, save it to server and then use CUPS to print it out from Linux. What a pain ...\nHow I see it, the days of ML-4500 are counted ... especially when my favorite hardware supplier has very nice color laser network printer for a great price :-).\n","date":"November 22, 2007","externalUrl":null,"permalink":"/posts/2007-11-22-little-pains-of-switching/","section":"Posts","summary":"I have been running the Unix only workstations for over a week now. During this week, I have managed to clean up and convert two Windows boxes to VMWARE virtual machines, but actually had to resort to use the VM's only in two cases. Everything else worked just fine.\nThe first case was requirement to review an non-trivial Excel file. Normally, Numbers does very decent job when it comes to loading Excel files and for the most the remaining cases, the OpenOffice (in it's more polished Cocoa version NeoOffice) works just fine. Well - as long as you do not open spreadsheet with pivot tables. In my case, the spreadsheet contained pivot tables and charts based on these tables. Numbers warned during import that this feature is not supported and the converted spreadsheet was very good looking - nicer that in Excel, but not quite so functional :-). Strangely enough, the charts were imported OK but lost the drill-down capabilities. After trying out the NeoOffice, the imported spreadsheet had retained some pivot capabilities of the original, but lost charts completely. The only resort was falling back to Office 2003 in virtual machine and using Excel. Fortunately one of the two VM's created from old hardware had Office 2003 installed, so that worked out OK.\n","title":"Little pains of switching","type":"post"},{"content":"Today is a special day for this blog as two bit boundaries were crossed. This is post number 256, which means that I have used all 8 bit numbers for numbering and jumped into nine bit space. The byte is not enough any more - vive la 0x100.\nAnother boundary crossed today is number of hits as tracked by Wordpress (which does not count my visits). In this case the number reached and crossed was 0x8000 or 32768 decimal, which brings us to upper half of the 16 bit address space. From today, full 16 bit counter must be used - and it must be even \"unsigned short int\" :-).\nNot much blogging during weekend as I am still catching up with my de-cluttering project, enforced on me by the renovation - both in digital and physical world. The goal is to reduce number of physical computers in my office by three - to four from 7. It is unbelievable how much time it takes to clean up 4 year old Windows installation, remove all the junk and back-up what needs to be preserved. For every removed physical machine, at least one virtual is created, therefore the absolute number of used IP's actually grows ...\nSo far, I managed to get rid of old desktop (AMD Athlon 1800, 1 GB RAM, 2x120 GB HDD), even much older desktop running Win2000 used as Oracle DB server (P-III Celeron 400 MHz, 384 MB RAM, 40 GB HDD) and last one to clean up is another P-III - former Linux Samba Server (120 GB HDD, 512 MB RAM if I am not mistaken). I have tried out the VMWare convertor and created 10 GB virtual machines from both desktop and Oracle server using VMWare importer It is amazing how much faster the virtual machine runs on a Macbook Pro than it did on old hardware.\nOh btw, if you are in Ottawa and want two old P3 machines absolutely free for any charity or other worthy purpose, email me at firstname dot lastname at gmail. Machines are in good working condition - but without Windows. If it is for charity or school or something similar, I am willing even to help putting on a Linux distribution and deliver them to your place - if it is in reasonable distance between downtown and Kanata. The only quite fast machine - Athlon - is already gone, my son grabbed it to build some sort of digital TV recorder using Myth-TV. I do not watch TV, but I am quite curious how it will work.\n","date":"November 19, 2007","externalUrl":null,"permalink":"/posts/2007-11-19-crossing-bit-boundaries/","section":"Posts","summary":"Today is a special day for this blog as two bit boundaries were crossed. This is post number 256, which means that I have used all 8 bit numbers for numbering and jumped into nine bit space. The byte is not enough any more - vive la 0x100.\nAnother boundary crossed today is number of hits as tracked by Wordpress (which does not count my visits). In this case the number reached and crossed was 0x8000 or 32768 decimal, which brings us to upper half of the 16 bit address space. From today, full 16 bit counter must be used - and it must be even \"unsigned short int\" :-).\n","title":"Crossing bit boundaries","type":"post"},{"content":"On previous weekend I had great opportunity to spend a lot of time listening to books and podcasts. The opportunity was long drive to Quebec City and back, plus the two days spent walking around with camera, taking pictures, enjoying the differences in style and architecture and listening to Seth Godin's book - Small is the new big.\nThere is nothing in this book that would actually require to drive almost 500 km one way - you can comfortably get the same benefit out of it without moving out from your favorite sofa, walking around your neighborhood or on a treadmill (hi Joel). The real reason being in the capitol of La Belle Province was Skate Canada - Grand Prix competion in figure skating. And while my wife was watching Jeff Buttle, Joannie Rochette and many others - which is her favorite leisure time activity, I was walking, taking pictures and listening - which is mine.\nThe book is very well suited for listening while taking pictures. It consists of short comments on large number of topics - business and life related, presented in alphabetical order. This allows to do frequent stops for shots without loosing the context. If you now think that it must be boring to listen something resembling a lexicon you are wrong. Seth is original, often provocative and inconventional, sometimes \"common-sensy\" obvious, but never boring. I was very surprised how interesting can be a book from an expert in area of marketing - something that I never had any admiration for (or high opinion about). If you are hardcore techie like me with the same prejudice again something so non-geeky and slippery as marketing, give Seth a chance - you may be surprised.\nRecommended.\n","date":"November 16, 2007","externalUrl":null,"permalink":"/posts/2007-11-16-book-recommendation-seth-godin-small-is-the-new-big/","section":"Posts","summary":"On previous weekend I had great opportunity to spend a lot of time listening to books and podcasts. The opportunity was long drive to Quebec City and back, plus the two days spent walking around with camera, taking pictures, enjoying the differences in style and architecture and listening to Seth Godin's book - Small is the new big.\nThere is nothing in this book that would actually require to drive almost 500 km one way - you can comfortably get the same benefit out of it without moving out from your favorite sofa, walking around your neighborhood or on a treadmill (hi Joel). The real reason being in the capitol of La Belle Province was Skate Canada - Grand Prix competion in figure skating. And while my wife was watching Jeff Buttle, Joannie Rochette and many others - which is her favorite leisure time activity, I was walking, taking pictures and listening - which is mine.\n","title":"Book recommendation: Seth Godin - Small is the new big","type":"post"},{"content":"I have already worked through full week solely on Mac and Leopard platform with excellent results. The productivity in using Java is actually higher, thanks to faster machine and Spaces allowing to have opened few Firefox windows with Spring documentation, terminals for Ant builds, Tomcat, Eclipse and Spype/Adium to keep in touch. Spaces is about as good as having multiple monitors - the ability of switching between both with mouse and keyboard fits well in my working habits.\nSpeaking of Spaces - try this neat trick: press F8 and while in Space view, F9 for Expose. This will rearrange previously hidden windows and allow to click on the one you want. Another neat feature is possibility to tell application to show up in assigned space - use Preferences, Spaces and the '+' button for this.\nFirst time ever on Mac I had to print something and that was really interesting experience. After selecting Add printing, I was subconsciously expecting the dialog box asking to enter printer location URL or IP address and mentally getting ready to search for printer driver somewhere on the Net. The reality was different. Right after Add printer, OS-X somehow discovered both printer on network and I was ready to go without anything else to do on the black-and white laser. The second one (Konica-Minolta) did not have driver provided by the OS - something to finish up next week. I guess I should find out more about this Bonjour thing responsible for the printer discovery magic :-).\nAlso the Office documents compatibility got tested - both with iWork 08 and NeoOffice. Most documents converted without any issues - both Excel 2003 and Excel 2007 were perfectly readable in Numbers (and looked much nicer). I have experienced conversion issues with large complex document containing pivot tables and charts. Numbers notified that pivot tables cannot be converted and showed only charts, whereas NeoOffice sort-of converted the pivot tables but completely destroyed the charts. It looks like that having XP in virtual machine will be necessary after all - for situations like this. I have already installed Fusion and experimentally proved that the VM's created on Linux are transferable to Windows and Mac: I was able to install XP into VM created under Linux, saved binary state, moved to Windows, booted it there in VMWare Player and after installing ATG suite, the same VM was running with no issues at all in Fusion. Nice.\nI have also mostly solved the synchronization issue of two subtrees. The open source application JFileSync does almost everything I need - except integrated visual file compare. I am also evaluating the Path Finder which has tabs and maybe most of the TotalCommander functionality I was missing - without doing the two windows approach. So far, looks very promising !\n","date":"November 15, 2007","externalUrl":null,"permalink":"/posts/2007-11-15-leopard-in-business-environment-week-1/","section":"Posts","summary":"I have already worked through full week solely on Mac and Leopard platform with excellent results. The productivity in using Java is actually higher, thanks to faster machine and Spaces allowing to have opened few Firefox windows with Spring documentation, terminals for Ant builds, Tomcat, Eclipse and Spype/Adium to keep in touch. Spaces is about as good as having multiple monitors - the ability of switching between both with mouse and keyboard fits well in my working habits.\n","title":"Leopard in business environment - week 1","type":"post"},{"content":"Last year, when I got my first Mac, it was a wild ride of discoveries and trying out new software. As result I have ended up with many programs installed that I do not really need or use. Fortunately, the uninstall process is as simple as install and there is no registry that could get corrupted, so it was not really a big deal. With the new one, I am going to be much more selective what I put on the harddrive and what not.\nI've decided to keep track what I installed to make the reinstallation (should it be ever required) easier. Here is what I have installed so far:\niWork 08 - very nice replacement for Microsoft Word, Excel and Powerpoint.\nTextMate – \"THE editor\" - http://macromates.com/. Most amazing editor I have ever encountered, since Emacs. Similarly powerful (I have not really mastered it completely and mostly forgot the Emacs commands to make fair comparison) - but with UI that is nice and elegant (unlike Emacs which is super powerful but ugly like hell)\nEclipse - Java IDE most of our clients use\nNetbeans Ruby IDE - the other IDE, currently the best IDE for Ruby development\nAdium - chat client that can talk to MSN Messenger, Yahoo messenger and GoogleTalk. No voice, yet - this is what Skype and iChat's are for. QuickSilver - the launcher and much more. It is actually easier to use it than to explain it :-) CHMOX - reader for Microsoft compiled Help file format (.CHM).\nNeoOffice - I should not really need it with iWork, but until I test that the exported documents cause no troubles for the other on MS-Office, this is my \"plan B\"\nCord - open source Windows Remote Desktop client\nLibrary Books - nice menulet that alerts you when books are due for return to local library. Ottawa public library is supported. KeePassX - secure vault that stores your serial numbers, logins, passwords in very secure way. Open source, multi platform (OS-X, Linux, Windows) and the data files are fully compatible. iTerm - another terminal. May not be necessary, as the default Terminal looks pretty good in Leopard - but it is great to have an opensource alternative, should that not be the case :-)\nTransmission - bittorrent client\nJungleDisk - the Amazon S3 Service client. OmniOutliner Pro - the outliner. See the manual for details.\nVMWare Fusion - virtualization environment\nVLC - media player\nI have also installed whole bunch of Java libraries and tools (such as Ant, Spring framework, Tomcat, Glassfish, Jakarta Commons) and Ruby gems - but that's too much detail for the moment :-).\n","date":"November 12, 2007","externalUrl":null,"permalink":"/posts/2007-11-12-my-essential-os-x-toolset-part-1/","section":"Posts","summary":"Last year, when I got my first Mac, it was a wild ride of discoveries and trying out new software. As result I have ended up with many programs installed that I do not really need or use. Fortunately, the uninstall process is as simple as install and there is no registry that could get corrupted, so it was not really a big deal. With the new one, I am going to be much more selective what I put on the harddrive and what not.\n","title":"My Essential OS X toolset - part 1","type":"post"},{"content":"During the vacation, we stopped in small bookstore in Verona which was selling computer software as well. At the entrance, there was a poster showing smiling Finder's face, Apple logo and announcing reasons why you would want to make the big jump - il grande salto - to Mac platform. That is to explain the title :-)\nGrande Salto is exactly what I did. Without too much preparation or notice. Since Tuesday evening I am happy owner of the beautiful piece of hardware (17 inch 2.4 GHz Core 2 Duo Macbook Pro with 250 GB HDD and 4 GB of RAM) that is greatly complemented by the amazing software collection (OS X 10.5, iLife 08, iWork 08 and many others) running on it. I spent Wednesday playing with it and between 'Wows' and 'Ahhs' managed to setup the core applications I need for work: several configurations of Eclipse (with and without MyEclipseIDE), Netbeans with Ruby, couple of gems and of course THE editor. Then transferred the sources, installed Ant, Spring, Tomcat and couple of opensource packages (e.g. Jakarta Commons). And on Thursday, I jumped right into the field, to the client continuing in development of my current Java project in the place where I left it on Monday with Fujitsu N5100 running XP-ProSP2. As a plan B, I had my old notebook also with me - but did not have to resort to using it.\nThe switch was not easy and for few hours I had to fight old habits and muscle memory. As many years TotalCommander addict, I had created really fast and efficient workflows and habits how to move around. None of them was of course applicable. It is really hard to overcome these unconscious finger movements burned deep into your brain: F3 is File View, F4 is File Edit, F7 is create directory - when you have been using them for over 20 years since MS-DOS and Norton Commander. But eventually, I learned to appreciate and enjoy the New Ways. New Finder is really good and in combination with Spaces and Quicksilver allows at least as efficient ways - sometimes even better - how to accomplish things.\nAs I was expecting, using bash instead of pretty lame windows command shell is a big relief. I have forgotten 90% of my old shell script and command line edit keystroke skills, but it is still so much better. The file system operations are considerably faster and common tasks can be automated with minimal effort just by using symbolic links, simple scripts and shell variables. What is much better under Leopard is network connectivity - the way how it does browse and connect to Windows machines ...\nWorking in Eclipse is same as under Windows - only it looks better and is faster - but (to make it fair comparison) it MUST run faster on 2.4 GHz Core2 Duo 4GB than on 3.4 GHz P-IV with 1 GB. Ability to use two finger scrolls, quick desktop switches and great screen resolution (1920x1200) makes the Macbook Pro close to perfect developer workstation.\nI have still not found replacement for all features and tools I was using in Windows - but I am working on it. Most of them come from 3rd party software, not from OS. Right now, what I miss is (from TotalCommander):\n- convenient directory comparison and synchronization with good GUI (with embedded on-demand file diff)\n- transparent processing of the packed archives - TC makes them look and behave as directory sub-trees\n- opening shell in directory / creating file in directory - aka \"I am in the Project/demo/src directory now, please create the empty README.txt file here\". Mac works the other way - open editor with the new file and save the file to Project/demo/src/README.txt. Which is not necessarily worse, but just (still) against my instincts. I was used to get to directory first and press Shift-F4 (bound to start of Notepad++, prompting for name), or to click on TotalCommader toolbar icon \"Open command prompt in current directory\"\nAfter working two full days, I have not found any real issues and was extremly pleased with the Leopard user experience. It is hard to explain - the differences are subtle but in whole it feels so much better than any other OS. I have been using OS-X for over a year now, but only at home and for mostly hobby-projects or after hour hacks. This is an attempt to make Mac the foundation for work environment as well, and use Windows for .NET development only, running it inside virtual machine. And it is very different experience - in two days I have learned a lot and found out about many more things to discover.\nTo make the grande salto even more complete (and potentially devastating in case of bad landing ;-)), I have also during last week wiped out my desktop at Thinknostic and instead XP-Pro installed Fedora Linux with KDE desktop. With the Mac available and working mostly out of office I do not get so much time to spend on desktop - but it is good to have same platform on both places. I have already configured first few VMWARE virtual machines - with both Linux and Windows as guest OS. The Vmware player works great under Linux, I cannot wait until final version of the Fusion 1.1 is out to test on on the Mac.\n","date":"November 9, 2007","externalUrl":null,"permalink":"/posts/2007-11-09-ragioni-per-fare-il-grande-salto/","section":"Posts","summary":"During the vacation, we stopped in small bookstore in Verona which was selling computer software as well. At the entrance, there was a poster showing smiling Finder's face, Apple logo and announcing reasons why you would want to make the big jump - il grande salto - to Mac platform. That is to explain the title :-)\nGrande Salto is exactly what I did. Without too much preparation or notice. Since Tuesday evening I am happy owner of the beautiful piece of hardware (17 inch 2.4 GHz Core 2 Duo Macbook Pro with 250 GB HDD and 4 GB of RAM) that is greatly complemented by the amazing software collection (OS X 10.5, iLife 08, iWork 08 and many others) running on it. I spent Wednesday playing with it and between 'Wows' and 'Ahhs' managed to setup the core applications I need for work: several configurations of Eclipse (with and without MyEclipseIDE), Netbeans with Ruby, couple of gems and of course THE editor. Then transferred the sources, installed Ant, Spring, Tomcat and couple of opensource packages (e.g. Jakarta Commons). And on Thursday, I jumped right into the field, to the client continuing in development of my current Java project in the place where I left it on Monday with Fujitsu N5100 running XP-ProSP2. As a plan B, I had my old notebook also with me - but did not have to resort to using it.\n","title":"Ragioni per fare il grande salto","type":"post"},{"content":"Trying to install ATG on the Linux platform turned out to be not completely hickup-free. The default installer died with the following message:\n$ ./ATG2007.1.bin\u0026gt; Preparing to install...\u0026gt; Extracting the installation resources from the installer archive...\u0026gt; Configuring the installer for this system\u0026#39;s environment...\u0026gt; awk: error while loading shared libraries: libdl.so.2: cannot open shared object file: No such file or directory\u0026gt; dirname: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u0026gt; /bin/ls: error while loading shared libraries: librt.so.1: cannot open shared object file: No such file or directory\u0026gt; basename: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u0026gt; dirname: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u0026gt; basename: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory[/sourcecode]\u0026gt; Fortunately, the fix was easy after I found out what went wrong: incorrect assumption about kernel version. To make it work, this \u0026#34;hack\u0026#34; helped:\u0026gt; [sourcecode language=\u0026#39;css\u0026#39;]\u0026gt; $ mv ATG2007.1.bin ATG2007.1.bin.orig\u0026gt; $ cat ATG2007.1.bin.orig | sed \u0026#34;s/export LD_ASSUME_KERNEL/#xport LD_ASSUME_KERNEL/\u0026#34; \u0026amp;gt;ATG2007-1.bin None of this of course happens on Windows - oh, yes - the joys of not swimming with the crowd :-). You will encounter issues otherwise unknown - but also learn something in the process.\n","date":"November 8, 2007","externalUrl":null,"permalink":"/posts/2007-11-08-installing-atg-on-fedora-core/","section":"Posts","summary":"Trying to install ATG on the Linux platform turned out to be not completely hickup-free. The default installer died with the following message:\n$ ./ATG2007.1.bin\u003e Preparing to install...\u003e Extracting the installation resources from the installer archive...\u003e Configuring the installer for this system's environment...\u003e awk: error while loading shared libraries: libdl.so.2: cannot open shared object file: No such file or directory\u003e dirname: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u003e /bin/ls: error while loading shared libraries: librt.so.1: cannot open shared object file: No such file or directory\u003e basename: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u003e dirname: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory\u003e basename: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory[/sourcecode]\u003e Fortunately, the fix was easy after I found out what went wrong: incorrect assumption about kernel version. To make it work, this \"hack\" helped:\u003e [sourcecode language='css']\u003e $ mv ATG2007.1.bin ATG2007.1.bin.orig\u003e $ cat ATG2007.1.bin.orig | sed \"s/export LD_ASSUME_KERNEL/#xport LD_ASSUME_KERNEL/\" \u0026gt;ATG2007-1.bin None of this of course happens on Windows - oh, yes - the joys of not swimming with the crowd :-). You will encounter issues otherwise unknown - but also learn something in the process.\n","title":"Installing ATG on Fedora Core","type":"post"},{"content":"The combination of 17\" screen with Leopard's visual appeal is pure beauty.\nUnlike assumed, the Leopard does NOT (yet) come preinstalled on hard disk. There is a DVD which will install it. I have decided to erase everything and start from scratch. The install took about 45 minutes and had zero problems. The only confusing part was that after erasing harddrive you also erase iLife and need to reinstall it. On the Web site, Apple shows an image of two DVD's - Leopard and iLife'08. There is however no iLife install DVD in the package.\nWhat you have to do is to go to \"old\" disks - the package also contains two DVD's with version 10.4.10 and on first you can find installer for bundled software. This gives you the iLife 08 goodies such as iDVD or iMovie.\nNow after tomorrow memory swap (MBP is going to get 4GB, the Macbook will receive the abandoned 2GB) I have to clean up the Mackbook hard drive, install software on my new notebook (so far I have installed only iWork, Firefox and TextMate) and get busy :-).\n","date":"November 6, 2007","externalUrl":null,"permalink":"/posts/2007-11-06-macbook-pro-arrived/","section":"Posts","summary":"The combination of 17\" screen with Leopard's visual appeal is pure beauty.\nUnlike assumed, the Leopard does NOT (yet) come preinstalled on hard disk. There is a DVD which will install it. I have decided to erase everything and start from scratch. The install took about 45 minutes and had zero problems. The only confusing part was that after erasing harddrive you also erase iLife and need to reinstall it. On the Web site, Apple shows an image of two DVD's - Leopard and iLife'08. There is however no iLife install DVD in the package.\n","title":"Macbook Pro arrived","type":"post"},{"content":"I am in the middle of a non-computer related project. Last week we have decided to get rid of carpeting in my home office and library and to put in the hardwood floor. My wife picked the wood and color, I picked the contractor, with my son's help we moved out the furniture and the renovation started. The most painful thing was shutting down and disconnecting all the computers and servers - only the lonely router is hanging on the wall and suffering the dust and noise of the power tools. As result, my family is now server-less and until we finish and connect them back, we have to survive using the notebooks only. Fortunately, I have at least one notebook available for each household member, except the cat. Even more fortunately, she (the cat) does not mind.\nSurprisingly, this project reminded me of something that is so familiar when you are working in enterprise IT environment and deal with real life systems and real companies: you cannot do just one thing. After we uncovered the carpets, we have discovered few hidden issues that had to be fixed before we could put the hardwood in. In process of fixing it, another issue popped up and we ended up replacing the plywood that was under the carpet. As result, what was supposed to be done in 2-3 days, will take twice as long and will carry according price tag. In all this we are extremely lucky having very good, capable, hard working and honest contractor doing the work.\nSo, does all this renovation have anything else in common with software engineering? I think it does. Year or so ago, we had this discussion about metaphors, paradigms and models for the software development process. One of the discussion's topics was why is our (presumably engineering) profession so bad in estimating the time and effort required. Look at the guys building the houses - Steve challenged us - they can tell with 5-10% precision when they will be finished and how much will it cost. Even better, when customer changes his/her mind in the middle of the project, the impact of the change on timeline and price can be determined with fairly high accuracy.\nWe have talked about obvious differences between building a house and building a software system. The house is pretty much always the same - can be bigger or smaller, but the variations are very small compared to possibilities of software systems. There is very small selection of materials, the components are well standardized and the process of building has been tested and fine tuned on millions of houses built. The workforce in construction business is very much standardized as well - the productivity can be easily measured and deviations between the most and least productive worker are much smaller than in software world. The laws of physics help too - by making the completely wrong combinations of components more obvious and easier to spot. In short, construction of a house is bad metaphor for building a software system.\nWhat seems to be much better metaphor (if we have to stay in the realms of construction business) is house renovation. Here you have to make assumptions and will make discoveries as you progress - and this maps nicely to the process of requirement \"gathering\" (whoever created the term gathering was idealist, in reality it is much closer to digging for requirements, but back to the topic). You start assuming that your job is to put in hardwood floor - or to integrate two software systems. In reality, your job is to resolve unknown number of problems of unknown complexity in order to even start.\nYou have the legacy of existing house, plumbing, infrastructure - similar as you have legacy enterprise systems, databases, data feeds, business owners and so on. You may be aware of some them before you start, but their true size, nature, status and complex interdepencies will became fully understood only during the process of renovation (or integration).\nSo what is the moral of the story and what is the right approach ? I have no answer that would work in every situation. What worked for me - is honest communication and transparent decisions. Make sure that the customer understands what is included in the estimate, what are your assumptions and what can potentially be hidden issues if there is an indication you may find some. Whenever you discover something that may change the scope, do not delay telling the client and make sure he/she understands all possible pathways and their consequences.\nBe generous - if you need to invest extra time to make sure the recommended decision is the best option for the client, invest that effort regardless whether the cost will be covered by the client. If you go that extra mile, in long run you will be always rewarded - with repeated business, better rate or at least the good karma for doing the right thing.\nDocument all agreements, discoveries, options presented and decisions - they may be great reference when facing similar decision in your next assignment. And sometimes the document trail you leave behind may be only existing documentation of the system in question. The contractor that comes next, will thank you for that. If you do your part properly, that somebody may be the future you.\n","date":"November 5, 2007","externalUrl":null,"permalink":"/posts/2007-11-05-on-hardwood-floors-and-software-engineering/","section":"Posts","summary":"I am in the middle of a non-computer related project. Last week we have decided to get rid of carpeting in my home office and library and to put in the hardwood floor. My wife picked the wood and color, I picked the contractor, with my son's help we moved out the furniture and the renovation started. The most painful thing was shutting down and disconnecting all the computers and servers - only the lonely router is hanging on the wall and suffering the dust and noise of the power tools. As result, my family is now server-less and until we finish and connect them back, we have to survive using the notebooks only. Fortunately, I have at least one notebook available for each household member, except the cat. Even more fortunately, she (the cat) does not mind.\n","title":"On hardwood floors and software engineering","type":"post"},{"content":"With my new Macbook Pro on the way from China, I have started the big consolidation of hardware and software platforms. The goal is to improve the change management of software development environments, increase mobility and increase stability of the environments.\nThe way how I am going to do that is moving all \"fragile\" environments to virtual machines. My most fragile environment is Windows XP (I am still resisting Vista). What I mean \"fragile\" is well known \"software rot\" of the developers machine, caused by frequent installs and uninstalls (or upgrades) of components, tools, etc. After some time (which varies by the kind and frequency of installs), the machine becomes more and more sluggish, registry bloated and occurrence of weird things more frequent - up to the point that developer decides to blow off the Windows install and start from scratch.\nThis operating system \"cancer\" can be slowed down a lot in virtual machine by using several baselines: clean install, clean install with Visual Studio, etc. Whenever you need to roll back an install (or test a new Beta version of Visual Studio, many of which were notoriously known to be uninstallable) you just throw away latest VM status. It takes some discipline to keep things documented and to keep the images up to date with all the patches and updates - which may be a challenge ;-).\nAs host platform I will be using OS X (for the notebook) and Linux (for the desktop). I could use Windows as host on desktop, but the latest series of BSOD I have experienced on my barely one year old desktop machine made me to rethink that. It is time again after few years, to make another try of Linux - for three main reasons. First is to find out whether there is indeed some hardware problem with the machine (the memory tests were showing no issues) or whether it is (as usual) some bug in third-party driver. It is so annoying that any unknown sloppy programming job of some never-heard-of company can shut down XP completely - thanks to Microsoft's decision to put pretty much everything into kernel space :-(. If Linux works OK, the point is proven - it WAS a software problem.\nThe second reason for Linux is that several of our clients are using Linux and virtualization and we want to recreate comparable environment in the lab for evaluation and testing purposes. We had lot of fun finding out why did the Oracle Advanced Queueing stop communicating with ATG Dynamo service components recently and I am sure this is not the only scenario where moving physical server into virtualized subtly changes environment up to the point of breaking it :-)\nAnd the third reason for Linux as a host is convenience having same kind of OS as host on notebook and workstation and power of that OS. Shared availability of tools such as bash and Unix file tools can make administration and automatization much simpler.\nI have not made final decision whether to stay with Parallels (which is available for all three platforms or switch to VMWARE. Right now, I am leaning more towards VMWARE - I have tested it out on Linux and Windows and found it working very well - at least the free player version. The VMWARE Server's UI performance on Windows host was not very impressive - but I guess that was not what it was written for. The reviews of performance I have read favorize VMWARE on Mac and very important factor is availability of ready-made pre-built images - software appliances from Marketplace. Neither have I selected the Linux Distro - albeit it will be one of the major ones. As the guest OS I will be using XP - the only way how to do the .NET development. As well as Linux, which can be useful to overcome the lack of Java 6 on Mac (until resolved) as also to contain various database environments into their own appliance (MySQL, Oracle, PostgreSQL). I want also compare user experience when doing Java development on Linux and Mac with respect to on Windows - in recent discussions on Javalobby so many people were claiming superiority of Linux for developer's workstation that I cannot resist the temptation :-).\nI am really curious how this will work when implemented. The only scenario where the above described setup would not work is the kind of project we did last year: depending on hardware devices physically attached to the PC by Firewire or even custom board (such as biometric camera with face recognition software or secure document scanner). Right now, we have the the luxury of not needing anything like this - which is great time to try it out ...\n","date":"November 1, 2007","externalUrl":null,"permalink":"/posts/2007-11-01-going-mostly-virtual/","section":"Posts","summary":"With my new Macbook Pro on the way from China, I have started the big consolidation of hardware and software platforms. The goal is to improve the change management of software development environments, increase mobility and increase stability of the environments.\nThe way how I am going to do that is moving all \"fragile\" environments to virtual machines. My most fragile environment is Windows XP (I am still resisting Vista). What I mean \"fragile\" is well known \"software rot\" of the developers machine, caused by frequent installs and uninstalls (or upgrades) of components, tools, etc. After some time (which varies by the kind and frequency of installs), the machine becomes more and more sluggish, registry bloated and occurrence of weird things more frequent - up to the point that developer decides to blow off the Windows install and start from scratch.\n","title":"Going (mostly) virtual","type":"post"},{"content":"Since the big meow on Friday, lot of unhappy people had been talking and blogging about how terrible and unacceptable is the absence of the Java 6 from the Leopard. Some post were sounding very dramatic \"I would not buy Mac if I only knew ...\" - which is a bit silly. The Leopard's 300 new features were posted and touted and hyped for two weeks. Some of the \"great\" improvements were actually fairly modest improvements - so it was OBVIOUS that Java 6 is not going to be included because it would definitely make the list. QED.\nSo what happened since Friday October 26th that made an extremly popular Java development platform (Mac) suddenly so awfully inadequate and such a bad choice ? I mean - when you were reading the Java related blogs during last year, majority of the screenshots from Netbeans or Eclipse were coming from the good looking and polished Tiger UI. How come that it did not matter then that it did only run Java 5 and in even lower version ?\nI agree that it would be much better if Mac would contain the Java 6 and that Apple should do much better job in outlining the plans and the roadmap for supporting new Java versions. But is it really such a big deal if we have to wait few more months ? Not from my point of view - which may be shared with some more developers in enterprise world. The thing is that industry does not move as quickly as we developers do and like. Many of our clients are still on 1.4, some even on 1.3 version - and have no rush to move up. Nobody from them is really asking for Java 6, the upgrades are being performed to Java 5 in the best case. There must be a really good business case to justify the upgrade - because you cannot just recompile server side application from Java 1.3 to Java 5 or 6. Not in real world of J2EE.\nShould the transition be between Java 1.4 and Java 5 and should we be prevented to use Java 5 - yes, that would be a big deal. Language enhancements between these two releases were very important from developer's point of view. Java 5 was a great upgrade, similar in scope to jump from C# 1.0 to 2.0. But the upgrade to version 6 is much less dramatic. There are performance gains and optimizations - yes, but in most cases Java 5 or even 1.4 is fast enough, so unless you have performance issue this is not the key. It has better interoperability between .NET and Java web services - if you are in heterogeneous environment, these may come handy. There are also many improvements in version 6 that will make developer's life easier (debugging enhancements, scripting and dynamic languages) but from application's business owner's point of view these are not really that important, certainly not showstoppers or must have's. Many of these can be achieved either using tools or enhancements outside of the JDK.\nIt is sad that Java does not seem to be a top priority for Apple - but delivering major software creation is always a juggling act between time and resources available and final featureset - as we have seen in 5 years delay of the other major OS with same story of silent dropping of features. What makes it harder to digest for Java developers is that Apple seemingly did not have enough resources and enough time to finish Java 6 for Leopard release - even one year later after it was available on other platforms - and to add insult to injury, there somehow was time enough and resources available to get in much more recent advancements from some competitive technologies - such as Ruby on Rails.\nI think that - as often before - the general perception is influenced by the loudest unhappy voices, while the more reasonable are not so articulate and less notable. I believe there will be several major Leopard updates coming in next few months - like fixing the bugs and adding read/write to ZFS functionality (which is to certain degree available now) - and hope that one of these updates will bring Java 6. In the mean time, I will happily use Java 5 knowing that it can do everything my Java projects need.\nLack of Java 6 on one of the three major client platforms can be seen from two angles: you can say \"I am not going to use OS X because it does not have Java 6\". Or you can say \"I am not going to use Java 6 until it is available on all major platforms\".\nOr you can play an optimist and try to find something positive in lack of Java 6 on Leopard: we all know that SDK for iPhone /iPod touch is coming in February 2008. One of the reasons why the SDK is delayed is security concerns - Steve Jobs said the company is trying to do two things at once -- provide an open platform to developers while protecting iPhone users from viruses, Trojans and other malware. Hmmm - does not this sound like providing a sandbox - something that Java is excellent at ? Is it too good to be true that delay of Java 6 may be a good news ?\n","date":"October 31, 2007","externalUrl":null,"permalink":"/posts/2007-10-31-missing-java-6-on-leopard-is-sky-really-falling/","section":"Posts","summary":"Since the big meow on Friday, lot of unhappy people had been talking and blogging about how terrible and unacceptable is the absence of the Java 6 from the Leopard. Some post were sounding very dramatic \"I would not buy Mac if I only knew ...\" - which is a bit silly. The Leopard's 300 new features were posted and touted and hyped for two weeks. Some of the \"great\" improvements were actually fairly modest improvements - so it was OBVIOUS that Java 6 is not going to be included because it would definitely make the list. QED.\n","title":"Missing Java 6 on Leopard - is sky really falling ?","type":"post"},{"content":"I have to confess, I did it :-). But no, I did NOT do it right away after Friday 6PM when Leopard became publically available. I managed to wait for whole 5 hours... partly because I was not sure whether the 6PM is local time or Cupertino time - and partly because the Apple store was stubbornly saying that my MBPro would ship with Tiger. At about 10:30 there was a \"sticker\" saying that all new Macs will be shipped with Leopard ... and after that, you have to agree I had no choice ....\nI have also purchased the Apple Developer's Connection select subscription - aka ADC. It is sort of MSDN for OS-X platform, giving you access to interim release. It was cheaper than MSDN, but frankly - MSDN contains by order of magnitude more software therefore it is not a fair comparison. Some people I know would say it is not a fair comparison when it comes to quality of the software - but this is up to everyone to decide for himself. Unlike MSDN the ADC gives you discount for hardware purchase which in case of MacBook Pro paid for the ADC itself plus over $100 savings. The more you spend the more you save ....\nI expect the Macbook Pro to arrive in 6-10 days. It is going to be my main mobile workstation, serving all Java and Ruby development needs directly - and (should there be any need) using either a remote desktop or running Windows in a virtual machine for .NET development. I have still not decided whether I will upgrade Parallels or buy VMWare Fusion. On one hand, Parallels did not impress me with their upgrade policy and reviews I have seen show that Fusion performs better - but my experience from using VMServer on Windows and running Linux inside showed pretty unimpressive user interface speed - much worse that VMWare player and close to unusable. I guess first hand experience is required to see how does Linux and Windows behave in VM under Leopard ...\n","date":"October 28, 2007","externalUrl":null,"permalink":"/posts/2007-10-28-ordered-a-macbook-pro/","section":"Posts","summary":"I have to confess, I did it :-). But no, I did NOT do it right away after Friday 6PM when Leopard became publically available. I managed to wait for whole 5 hours... partly because I was not sure whether the 6PM is local time or Cupertino time - and partly because the Apple store was stubbornly saying that my MBPro would ship with Tiger. At about 10:30 there was a \"sticker\" saying that all new Macs will be shipped with Leopard ... and after that, you have to agree I had no choice ....\n","title":"Ordered a Macbook Pro","type":"post"},{"content":"I have been using it for over half year now and was very happy with it. After I did today hear Steve Gibson mentioning (and recommending) it on Security Now!, I want to share my experience and add my vote of confidence.\nThe solution is Amazon S3 service (Simple Storage Service), fantastically affordable system to store your data securely on-line. You pay as you go - the size is unlimited and you are charged only for what you store and bandwidth you consume. Fantastically affordable means 15 cents for gigabyte-month storage and 10 cents for gigabyte transfer in / 18 cents for transfer out which will drop to 13 cents if you use it more. This means that to store my approximately 30 GB collection of pictures I need to upload them first (for $3) and then pay $4.50 monthly for storage - plus the download traffic. But of course, I am not using it for the images because I really need and like the nice album user interface which SmugMug provides. But to archive documents - this is just the perfect solution.\nThe S3 is focusing on developers and the service is accessible via Web service. You can choose from many available implementations for their API - in Java, Python, Perl, C#, VB, Ruby - you name it. For non programmers, there are client tools available that completely abstract the storage access and make the S3 appear as just another drive. From many clients avialable, I have selected (as well as Steve and Leo did) the Jungledisk. Unlike some other services that are trying to stand between you and your storage, take over not only data flow but more importantly money flow (and often charge fat premium), the good guys at Jungledisk just want to sell you the client and let you pay directly only Amazon fees to Amazon. The price for the client is just $20 - it is no-brainer. For this price you will get client version for all three major platforms (Mac, Linux, Windows) as well as source code of the \"engine\" part of the solution - in case you want to access same data through UI or programmatically.\nAfter installation, the S3 will appear as another disc under windows or network volume on OS-X (I did not try Linux - yet). Jungledisk contains scheduler and can do automatic backup of defined parts of your disc to S3 - or you can use it for manual backup, as a very reliable and somehow slower external disc.\nThe big issue with remote storage of sensitive documents is security: can you really trust with your precious data to a third party (even if that part is Amazon) ? I think this is up to anyone to decide - but the S3 comes pretty close to my definition of secure-enough system and Jungledisk plays along very nicely. All traffic between you and Amazon is of course encrypted (SSL) and your data is stored as encrypted as well, by default using a private key that Amazon provides you. This allows key recovery - but also allows (in theory) that someone on Amazon side could read your files. If you want however, you can generate your own key pair and use it to encrypt the data - and all you need to do is properly configure your client Jungledisk. Or if you are really paranoid you can encrypt your data even before they even get to Jungledisk and Amazon - if you want to exchange convenience and easy of use for more security. In the last two cases, nobody on the earth will be able to read your files - but if you loose your key, you will need few million years to break it :-).\nGive S3/JungleDisk a try - you may like it too ...\nPS: If you are curious about performance and want more than my subjective feeling of \"very reasonble\" - read this.\nPPS: The Smugmug actually *is* running on Amazon s3 - but because they use hundreds of terrabytes of space, obviously were able to get the storage for a wholesale price. The $59.95 / year membership of Smugmug would buy you on S3 about 15-25 GB storage and reasonable usage. As most people have less than 15 GB images, the Smugmug can actually make some money and employ really talented designers.\n","date":"October 25, 2007","externalUrl":null,"permalink":"/posts/2007-10-25-great-solution-for-offsite-backup/","section":"Posts","summary":"I have been using it for over half year now and was very happy with it. After I did today hear Steve Gibson mentioning (and recommending) it on Security Now!, I want to share my experience and add my vote of confidence.\nThe solution is Amazon S3 service (Simple Storage Service), fantastically affordable system to store your data securely on-line. You pay as you go - the size is unlimited and you are charged only for what you store and bandwidth you consume. Fantastically affordable means 15 cents for gigabyte-month storage and 10 cents for gigabyte transfer in / 18 cents for transfer out which will drop to 13 cents if you use it more. This means that to store my approximately 30 GB collection of pictures I need to upload them first (for $3) and then pay $4.50 monthly for storage - plus the download traffic. But of course, I am not using it for the images because I really need and like the nice album user interface which SmugMug provides. But to archive documents - this is just the perfect solution.\n","title":"Great solution for offsite backup","type":"post"},{"content":"Audiobooks and podcasts can be an excellent way how improve your vocabulary and improve your English. If you are suffering of \"written English only\" syndrome, this may be an excellent remedy.\nWhat is that funny syndrome ? Many people from information technology (including myself) actually had to learn English twice. During the late teens and university we managed to get reasonable command of written English, so that we could (and did) read the books. Mostly about computers, of course. With that, we managed to build decent vocabulary of words which we knew ONLY in written form, and for many of them have absolutely no idea how this could be pronounced. This had two consequences: we had hard time to recognize the word when we heard for the first time pronounced the way how it should be pronounced - and - which is even worse - often our own audio rendering was be a big surprise to native anglophones :-) ...\nDuring second learning of the language, we eventually learned to recognize most of the words in spoken form and connected the two presentations - visual with spoken. What many people do to make this process faster - and what I did - is to use unabridged audio version of the book and follow along in printed book. Very efficient. You get printed copy of the book and as you listen, you can underline the words that you do not know or find worthy of of getting back to. If you are lazy enough, you can often pick a good translation of the book and look up how did the professional translator translate the word or the phrase.\nBecause the spoken language is quite different from the language used in books, these two sets of words will never be quite matching. There is however a good common ground between living, spoken language and the technical vocabulary of the books. It is podcast. If you had a written transcription of the podcast, you could do exactly the same thing as with audiobook. Indeed very few podcast have the transcription, because it is quite time consuming and most podcasters are barely covering the cost of producing the audio, but there is an excellent podcast that does have it: Security Now!.\nAnd it not only has a transcription, it an excellent one - almost perfect to the word. You can even choose the format of the text: html, pdf or pure text. You can even reading from Steve's web site and listen to the audio from the same site, all courtesy of GRC.com.\nSo if you are one of us not born in an English speaking country and want to impruv yer Engrish - go and grab the podcast, the transcript and follow along. There is nothing to loose - the only risk is that you may become very security conscious up to slightly paranoid - which may not be a bad strategy for living on-line :-)\nAnd if you like the podcast or learn anything from Steve and Leo - whether in area of English or computers, look at Steve's product for hard drive maintenance - Spinrite - which pays his bills and makes producing that great podcast possible.\n","date":"October 23, 2007","externalUrl":null,"permalink":"/posts/2007-10-23-good-way-how-to-improve-your-english/","section":"Posts","summary":"Audiobooks and podcasts can be an excellent way how improve your vocabulary and improve your English. If you are suffering of \"written English only\" syndrome, this may be an excellent remedy.\nWhat is that funny syndrome ? Many people from information technology (including myself) actually had to learn English twice. During the late teens and university we managed to get reasonable command of written English, so that we could (and did) read the books. Mostly about computers, of course. With that, we managed to build decent vocabulary of words which we knew ONLY in written form, and for many of them have absolutely no idea how this could be pronounced. This had two consequences: we had hard time to recognize the word when we heard for the first time pronounced the way how it should be pronounced - and - which is even worse - often our own audio rendering was be a big surprise to native anglophones :-) ...\n","title":"Good way how to improve your English","type":"post"},{"content":"Subtitled \"A little book that teaches you when to quit and when to stick\" by Seth Godin.\nSo what is the dip ? It is the strange valley after you start with something, causing that after initial quick success you will get worse before you can get better. Obstacles that you either overcome - or you quit. Seth explains that these obstacles are there for a reason - they separate those who want something badly enough from those who do not. We know them in various forms. Back at the university, the first 2 years packed with math were the dip. Very little of the math we have had to learn was actually really necessary - other that learn you how to think, how to study and in addition to that, separate those who really wants to have that Computer Science degree strong enough.\nGraphical rendering of the dip can look like this:\nDip is the division between the amateur photographer and a pro, between the a coder that can write a Excel macro or a quick applescript to the guy who can write the whole system. It requires different skills, different tools and in process of acquiring them, you will experience pain and difficulties. I am still in the dip with Ruby and Rails - after initial excitement with \"wow this was fast\" now comes \"how do I achieve this ? I can do it in J2EE and ASP.NET, but what would be the true Ruby/Rails way ?\".\nThe dip is not the only curve Seth is explaining. It is one of three \"evolution scenarios\" in pretty much any new venture: a job, school. The other two is flat curve of cul-de-sac, dead-end and the cliff - line going up to the breakpoint and then going down. With respect to quitting, there is a good point when to quit each curve: the flatline any time - the sooner the better, because it is just waste of time to stay and the cliff - any time before the breakpoint (after which is too late).\nThe book is not about the later two curves - it is about the dip. Seth describes various types of dips - in sales, manufacturing, education, relationships and impact of quitting in various phases. But the crucial question is when and where is it good idea to quit, what does it mean quitting and why quitting and failure can be different.\nThe old proverb says that \"Winners never quit and quitters never win\". Seth Godin challenges this and explains which is right time to quit and right time to stick. His advice makes sense - as you know, those who never win and never quit are idiots :-).\nThe Dip is a very short book and has excellent content to length ratio, very little deja-moo that so often fills the business strategy books. Recommended.\n","date":"October 21, 2007","externalUrl":null,"permalink":"/posts/2007-10-21-book-review-the-dip/","section":"Posts","summary":"Subtitled \"A little book that teaches you when to quit and when to stick\" by Seth Godin.\nSo what is the dip ? It is the strange valley after you start with something, causing that after initial quick success you will get worse before you can get better. Obstacles that you either overcome - or you quit. Seth explains that these obstacles are there for a reason - they separate those who want something badly enough from those who do not. We know them in various forms. Back at the university, the first 2 years packed with math were the dip. Very little of the math we have had to learn was actually really necessary - other that learn you how to think, how to study and in addition to that, separate those who really wants to have that Computer Science degree strong enough.\n","title":"Book review: The Dip","type":"post"},{"content":"I've spent lot of time today reading. I am catching up with my reading stack. Between stuff I've finished was: Breaking Windows : How Bill Gates Fumbled the Future of Microsoft\nThe impression ? Mixed feelings. Maybe I've expected something different. Lot's of details on internal politics and inner fights, not too flattering portrait of Bill G as control obsessed person with very questionable interpersonal skills. From technology perspective, very little what was both interesting and new. I can hardly tell how close to reality are the facts presented, but I often disagreed with the conclusion and analytics. Overall, it was probably worth the time spent on the book - the more you are into politics and relations, the more you may like it. If you are (as I was) expecting a view from more technology side and other stuff that matters, get another book.\nScary part was realization how every freaking email anybody ever wrote could be (and in fact, it indeed was) digged out and used to put its author into a fairly uncomfortable situation ! One should be very careful what one writes into an email, blog or even newsgroup ... It does not matter that you later fix it, change it or even delete it. Google and other search engines will find it before, cache and store it for eternity ...\n","date":"October 20, 2007","externalUrl":null,"permalink":"/posts/2007-10-20-book-mini-review-breaking-windows/","section":"Posts","summary":"I've spent lot of time today reading. I am catching up with my reading stack. Between stuff I've finished was: Breaking Windows : How Bill Gates Fumbled the Future of Microsoft\nThe impression ? Mixed feelings. Maybe I've expected something different. Lot's of details on internal politics and inner fights, not too flattering portrait of Bill G as control obsessed person with very questionable interpersonal skills. From technology perspective, very little what was both interesting and new. I can hardly tell how close to reality are the facts presented, but I often disagreed with the conclusion and analytics. Overall, it was probably worth the time spent on the book - the more you are into politics and relations, the more you may like it. If you are (as I was) expecting a view from more technology side and other stuff that matters, get another book.\n","title":"Book mini-review: Breaking Windows","type":"post"},{"content":"As I noticed on Apple Website, the SDK for developing 3rd party applications for iPhone/Touch will be available in February. This solves the biggest problem - offline reading - because with SDK, storing a downloaded copy will be trivial. It also will most likely fix the annoying lack of updatability of calendar and add few more interesting apps.\nIt is only matter of time until the other eBook formats will be be readable on iPod - such as CHM or PalmDoc (non-DRM-ed version).\nWith only 8 days remaining to Leopard and this anouncement, it feels like Christmas is here early this year :-)\n","date":"October 18, 2007","externalUrl":null,"permalink":"/posts/2007-10-18-ipod-touch-ebooks-reader-problem-solved/","section":"Posts","summary":"As I noticed on Apple Website, the SDK for developing 3rd party applications for iPhone/Touch will be available in February. This solves the biggest problem - offline reading - because with SDK, storing a downloaded copy will be trivial. It also will most likely fix the annoying lack of updatability of calendar and add few more interesting apps.\nIt is only matter of time until the other eBook formats will be be readable on iPod - such as CHM or PalmDoc (non-DRM-ed version).\n","title":"iPod Touch eBooks reader - problem solved","type":"post"},{"content":"Many good posts about programming, coding, business, aesthetics, with nice touch of wisdom, If you are into programming languages, do not miss this one, this and this. If you are more into process and management, try this and this or this. There also deeper and lighter stuff :-)\nAs Reg says about popular bloposts\nOne model for popular writing is that it panders to the reader's prejudices. Plain and simple. People like writing that validates them and especially their ideas. He certainly does validate mine, which is the reason why I made it blog of the day :-). Find for yourself.\n","date":"October 17, 2007","externalUrl":null,"permalink":"/posts/2007-10-17-botd-raganwald-by-reg-braithwaite/","section":"Posts","summary":"Many good posts about programming, coding, business, aesthetics, with nice touch of wisdom, If you are into programming languages, do not miss this one, this and this. If you are more into process and management, try this and this or this. There also deeper and lighter stuff :-)\nAs Reg says about popular bloposts\nOne model for popular writing is that it panders to the reader's prejudices. Plain and simple. People like writing that validates them and especially their ideas. ","title":"BOTD: Raganwald by Reg Braithwaite","type":"post"},{"content":"Every software developer will tell you how frustrating it is to trace problem in your application up to the point of third party library call (jar file or .dll / .so - make your choice) - and then have to resort to trial and error exploration, because you have no source code for that particular library module. For this very reason, most developers always prefer working with libraries or toolkits that comes with source code attached - if they have a choice. As a side benefit, these libraries are often free as a beer as well - but being able to understand the module is much more important as whether you have to pay license fee ...\nCouple of days ago there was an announcement about Microsoft publishing the source code for parts of the .NET framework 3.5. Few years ago such announcement would be a big deal. Now it was received mostly as \"yet another me-too move on MS behalf\" yawn - when many other really big companies are opensourcing many products, what options does Microsoft really have ? Robert Scoble calls it a \"defensive move\" and notes that as many times in last few years, Microsoft follows, rather then leads industry:\n... this isn’t open sourcing .NET, just releasing the source. That’s even lamer cause the other two have actually open sourced and are accepting submissions from the community. Cool, but when you’re last to do something does it really matter anymore?\nIndeed, what was done was not really opensourcing, only publishing the source - because license under which the code is available is none of accepted open source licenses (you are e.g. not allowed to modify the source). But regardless of the legalese details about the license, it is a good thing that developers are able to read the code and use it while debugging, right ? This was my first thought after reading the news. But as several people pointed out, you should be really careful before you look at the code. Steve Vaughan -Nichols even considers this to be an deliberate, malicious attempt to trap open source development - especially the Mono project.\nAt first it sounds crazy - why would Microsoft want to stop the Mono that exports the .NET technology to other platforms and this way helps to remove one of its main disadvantages against Java ? The one possible explanation - sounding a bit like conspiracy theory offers Kevin Hoffman (btw, it is really readworthy blog) in this post:\nMicrosoft is going to shut up a lot of whining Open Source people who claim that MS is just a big closed system. At First. If you ask me, the real reason for them releasing this source code is to make it more difficult for the mono project to create replicas of WPF, WinForms, and ASP.NET. With the source code available for all to see, it is far easier for Microsoft lawyers who might potentially engage in law suits in the future to claim that the people working on the Mono project stole their WPF code or their WinForms or ASP.NET code from the public BCL instead of building it on their own.\nand also\nWhat if, let's just say, Mono suddenly became as feature-complete as the regular .NET Framework. You think Microsoft wants to start losing server business (where it makes all of its real money...) because a bunch of .NET developers decided to run Linux .NET instead of Windows .NET? This may sound pretty wild speculation, but unfortunately just few days after release the source code, a patent infringement lawsuit was filed against RedHat and Novel. Not directly by Microsoft, but one cannot help to suspect some involvement from Redmond, considering the remark of Steve Ballmer that\nPeople who use Red Hat, at least with respect to our intellectual property, in a sense have an obligation to compensate us ..\nNow is this really a plot to derail open source project(s) - or just a symptoms that Microsoft became so large that two groups do not coordinate their steps and while one group (\"techies\") trying to evolve their platform and push .NET adoption release the source, other group (\"lawyers\") at the same time goes after money and very real threat of open source competition. Is it a malice or just an exceptionally bad timing ? Should we trust that it is actually OK to look at the source code ? Should we really trust a company that claims that open source software violates 235 their patents ?\nMake your own conclusions - but note that Mono development team contribution policy explicitly disallows even looking at the .NET source code.\nIf you have looked at Microsoft's implementation of .NET or their shared source code, you will not be able to contribute to Mono.\nThat may indicate something. Even if you never plan to contribute an open source project, consider what impact would have a potential legal dispute regarding intellectual property for your company, your product or your project - should it happen - and should you or your team have been using the source code in question, even if for debugging. IP lawsuits and very hard and very expensive and guess who is better prepared for a long legal fight :-).\nAs for myself, I will stay away from the hot source potato and use just the .NET documentation, however bad it is.\nThere is, after all so much great elegant and free source code to read (even in C#) ...\n","date":"October 17, 2007","externalUrl":null,"permalink":"/posts/2007-10-17-reading-source-code-considered-harmful/","section":"Posts","summary":"Every software developer will tell you how frustrating it is to trace problem in your application up to the point of third party library call (jar file or .dll / .so - make your choice) - and then have to resort to trial and error exploration, because you have no source code for that particular library module. For this very reason, most developers always prefer working with libraries or toolkits that comes with source code attached - if they have a choice. As a side benefit, these libraries are often free as a beer as well - but being able to understand the module is much more important as whether you have to pay license fee ...\n","title":"Reading source code considered harmful ?","type":"post"},{"content":"Thanks to sudden memory jump in my iPod (from 4GB Nano 2gen to 8 GB iPod touch) I have enough space to load some books in addition to podcasts. I normally do not like abridged versions, but the weather is getting worse so I do not get enough walking time for full versions. These two were both 3-4 disc long audio books.\nThe Google Story is interesting if you are into history of computing - because it describes the probably the largest transition in computing history - the evolution of World Wide Web to a platform and the evolution of the company that made the Web actually useful. I still remember how much time did it take in 1997/1998 to find anything relevant when the best way how to do this were directories (in early Yahoo! style) or AltaVista and hours and hours of paging through the irrelevant results. Then in early 1998 my friend Rajeeva (I was working in New Jersey at Merrill Lynch) made me aware of that company with funny empty looking page and strange name Google :). And now, 9 years later the shareprice of GOOG is well over $600 - just unbelievable.\nThe other book - The tipping point - is one of the \"must reads\", often quoted on the Web. After listening to it I fully agree - it is an important book. So important that I am going to get a treeware copy of it and re-read it in full and to find out how much damage did the abridgment do. The recording was not as great as the Google story - it was read by the author, which is seldom the best option. True, an author is the person with most complete understanding of the message - but it takes different skills, a professional actor to make the message sound as good as it can. Despite of that, I am glad I listened to it and hope you will as well.\n","date":"October 16, 2007","externalUrl":null,"permalink":"/posts/2007-10-16-book-recomendations-google-story-the-tipping-point/","section":"Posts","summary":"Thanks to sudden memory jump in my iPod (from 4GB Nano 2gen to 8 GB iPod touch) I have enough space to load some books in addition to podcasts. I normally do not like abridged versions, but the weather is getting worse so I do not get enough walking time for full versions. These two were both 3-4 disc long audio books.\nThe Google Story is interesting if you are into history of computing - because it describes the probably the largest transition in computing history - the evolution of World Wide Web to a platform and the evolution of the company that made the Web actually useful. I still remember how much time did it take in 1997/1998 to find anything relevant when the best way how to do this were directories (in early Yahoo! style) or AltaVista and hours and hours of paging through the irrelevant results. Then in early 1998 my friend Rajeeva (I was working in New Jersey at Merrill Lynch) made me aware of that company with funny empty looking page and strange name Google :). And now, 9 years later the shareprice of GOOG is well over $600 - just unbelievable.\n","title":"Book recomendations: Google Story, The Tipping Point","type":"post"},{"content":"Can you imagine a database table with 25000 (twenty five thousands) columns ? No, not rows, COLUMNS ! Now if you can do that, can you imagine displaying these columns in a datagrid (spreadsheet) on a screen ?\nThis is exactly what this guy is describing to be his requirements. I hope he did misunderstood or misread the requirements, because displaying 25000 columns on a screen is not only impossible - it is absolutely useless. How would the user interaction look like ? As one of the guys in the discussion pointed out, the table would be few hundred meters wide (assuming 1 cm cell and 19 inch monitor) ....\nMonsters like this happens when the person responsible for WHAT needs to be done goes step further and defines his/her idea about HOW it should be done. I have seen it many times when otherwise very good functional analyst gets overexcited in the process and goes beyond domain model - makes the actual data model part of the spec - despite lack of data modeling or database skills. This is ususally a guaranteed way how to end with bad data model and lot of unnecessary complexity later on.\nIn this case, showing peak information about customer the key is slicing the time interval (to show just some subset of information), proper using of graphs and aggregation of the values with drill-down functionality to show the details.\n","date":"October 15, 2007","externalUrl":null,"permalink":"/posts/2007-10-15-the-craziest-requirement-ive-ever-heard-about/","section":"Posts","summary":"Can you imagine a database table with 25000 (twenty five thousands) columns ? No, not rows, COLUMNS ! Now if you can do that, can you imagine displaying these columns in a datagrid (spreadsheet) on a screen ?\nThis is exactly what this guy is describing to be his requirements. I hope he did misunderstood or misread the requirements, because displaying 25000 columns on a screen is not only impossible - it is absolutely useless. How would the user interaction look like ? As one of the guys in the discussion pointed out, the table would be few hundred meters wide (assuming 1 cm cell and 19 inch monitor) ....\n","title":"The craziest requirement I've ever heard about","type":"post"},{"content":"So, I have finally got it. Only the 8 GB version as the 16 GB were sold out, but I just could not wait for another week :-). After playing with it for about 1.5 hour, I like it even more. The readability of Safari Web sites is excellent - I started to put together some links. Did not try too many sites yet, but the Dzone reads OK :-). Also the PDF book reading is very good - but that is no news. I guess I will have to put up some internal Apache access to my PDF eBooks from my bed :-).\nWireless gets connected right away and works very good with WPA. Comapared to Macbook, the signal strength indicator shows less bars (about same as my Windows notebooks) - but is still reliable enough. The only partially weird thing with wireless is when you change networks, after return the Safari insisted for some time to keep the Bridghead WiFi address. Speaking of which - Bridgehead got major black point today, as their WiFi does not support Safari. I never noticed it with Macbook - as I used mostly Firefox, but now I have no choice ! I am going to test Zavida - another coffeeshop with free WiFi soon.\nAfter I loaded podcasts, I went for a short 2 hour walk to test drive the iPod part of the gadget. Sound quality is hard to judge on spoken word. Leo sounded good as always and John C. Dvorak was as irresistibly cranky and funny as usual. Compared to my second gen Nano, the only disadvantage I have found so far is that you have actually look at the display when you need to stop play (in order to talk to somebody) or skip through the advertisement - whereas with clickwheel it can be done just by hand in your pocket.\n","date":"October 12, 2007","externalUrl":null,"permalink":"/posts/2007-10-12-ipod-touch-finally/","section":"Posts","summary":"So, I have finally got it. Only the 8 GB version as the 16 GB were sold out, but I just could not wait for another week :-). After playing with it for about 1.5 hour, I like it even more. The readability of Safari Web sites is excellent - I started to put together some links. Did not try too many sites yet, but the Dzone reads OK :-). Also the PDF book reading is very good - but that is no news. I guess I will have to put up some internal Apache access to my PDF eBooks from my bed :-).\n","title":"iPod touch - finally !","type":"post"},{"content":"","date":"October 11, 2007","externalUrl":null,"permalink":"/tags/ebooks/","section":"Tags","summary":"","title":"Ebooks","type":"tags"},{"content":"","date":"October 11, 2007","externalUrl":null,"permalink":"/tags/gadgets/","section":"Tags","summary":"","title":"Gadgets","type":"tags"},{"content":"No, I have not bought it yet, to big disappointment of Gabo and Shane - sorry guys. I wanted to buy it but all FutureShop stores in Ottawa are hopelessly sold out and on-line delivery is 7-10 business days - which I hope I will beat if these guys get new shipment (maybe tomorrow ?).\nI played with two demo pieces though for about 30 minutes, and here are the first impressions:\nThe screen is VERY nice. It reads well, and the touch interface is plain fantastic. No issues there. I tried the YouTube videos via wireless - worked OK, I also tried the web interface and was surprised that on such small screen the combination of touch interface and the way Safari renders pages gives you actually very usable browsing experience. Typing on the keyboard works better than I expected - almost no typos.\nI tried to open up a PDF file from Web and read it. It was best PDF reading experience so far (on the really small screen - I was comparing to PocketPCs). What works much better is that resizing of the PDF actually works - using the two fingers you can stretch the page and get the character size to what your eyes can handle. I guess it is even possible to read really small fonts this way - you can always increase them so that the page is bigger that the screen and move it around with your thumb while holding it in single hand (although you may get quite muscular thumb after a while :-))\nThe biggest issue right now is how to read offline. There is no built-in way how to save something from the Web on the device - neither HTML nor PDF - and iTunes will synchronize only music and videos (plus address, pictures and web bookmarks). So you cannot simple load few books and go ahead. This makes it unusable outside of home or other WiFi accessible content. There may be some solution soon as first hacks are appearing - and even officially sanctioned applications for iPhone and iTouch are multiplying nicely and some of them point to right direction. So either Apple will provide these options - or the hacks will bring them, it is only matter of time. The temptation is too large ... Another possibility is the direction of Google Gears which could pretty soon bring an offline mode for Web application. This most likely will need some cooperation between Google and Apple -but judging by the keynotes, Steve Jobs and Eric Schmidt are good buddies ;-) - let's keep our finger's crossed.\nI did not test the actual music playing - I had no headphones and the demo pieces had no music (this says something about the professional skills of the sales force in FS).\n","date":"October 11, 2007","externalUrl":null,"permalink":"/posts/2007-10-11-ipod-touch-first-impressions/","section":"Posts","summary":"No, I have not bought it yet, to big disappointment of Gabo and Shane - sorry guys. I wanted to buy it but all FutureShop stores in Ottawa are hopelessly sold out and on-line delivery is 7-10 business days - which I hope I will beat if these guys get new shipment (maybe tomorrow ?).\nI played with two demo pieces though for about 30 minutes, and here are the first impressions:\n","title":"iPod touch - first impressions","type":"post"},{"content":"Gerd Leonhard, co-author of the Future of Music book is making an experiment with his new book - The End of Control. He is publishing the chapters of the book as they appear in PDF format as well as MP3's on his website. First two chapters - \"Attention is the new currency\" and \"Copyright in the Age of Uncontrolled distribution\" are currently available for download / reading / listening.\nThe books tries to address very important questions on how will the new media business function in environment with little control over the distribution channel. Attempts to enforce control with technical tools were not very successful - just recall the Sony rootkit fiasco's, hacking the HD-DVD and others. Currently, there is strong movement away from DRM and towards non-crippledrestricted content.\nThe other line how the content owners try to enforce compliance is using legal muscles. The heavily publicized trial by jury to pay over $200'200 in damages for offering 24 songs on P2P network was presented in media mostly as big victory for the RIAA, but - as The Register points out - it may be easily Pyrrhic victory and may in the end backfire against the RIAA.\nMany people see labels and RIAA as a cross of dinosaur who forgot to die out and a leech sucking the money from the channel between the content creators and consumers. What are the new ways of distribution assuring the incentives for the authors without causing too much annoyance for the consumers, what are the business and legal implications of the new model are the themes into which the book will (hopefully) provide some insights. So far, looks very promissing.\nRecommended.\n","date":"October 9, 2007","externalUrl":null,"permalink":"/posts/2007-10-09-free-ebook-and-audiobook-on-media-business-and-distribution-control/","section":"Posts","summary":"Gerd Leonhard, co-author of the Future of Music book is making an experiment with his new book - The End of Control. He is publishing the chapters of the book as they appear in PDF format as well as MP3's on his website. First two chapters - \"Attention is the new currency\" and \"Copyright in the Age of Uncontrolled distribution\" are currently available for download / reading / listening.\nThe books tries to address very important questions on how will the new media business function in environment with little control over the distribution channel. Attempts to enforce control with technical tools were not very successful - just recall the Sony rootkit fiasco's, hacking the HD-DVD and others. Currently, there is strong movement away from DRM and towards non-crippledrestricted content.\n","title":"Free eBook and audiobook on media business and distribution control","type":"post"},{"content":"and similar plague (for some reason they were pretty active last few days):\nhttp://www.youtube.com/watch?v=un_PjRXV5l8\nI wish I could pull similar stunt - but I am not really a good actor and my accent would make it hard to believe. But it is hilarious anyway (video is a recording of phone call and contains text transcription ...). Enjoy.\nThanks to Peter M. for the link. I would link his blog or home page, if he had one :-).\n","date":"October 8, 2007","externalUrl":null,"permalink":"/posts/2007-10-08-great-way-how-to-deal-with-telemarketers/","section":"Posts","summary":"and similar plague (for some reason they were pretty active last few days):\nhttp://www.youtube.com/watch?v=un_PjRXV5l8\nI wish I could pull similar stunt - but I am not really a good actor and my accent would make it hard to believe. But it is hilarious anyway (video is a recording of phone call and contains text transcription ...). Enjoy.\nThanks to Peter M. for the link. I would link his blog or home page, if he had one :-).\n","title":"Great way how to deal with telemarketers","type":"post"},{"content":"Look how creatively did French government - more specifically Ministère de la culture et de la communication - approach even such mundane subject as the 404 page :-).\n","date":"October 7, 2007","externalUrl":null,"permalink":"/posts/2007-10-07-who-said-governments-web-pages-are-boring/","section":"Posts","summary":"Look how creatively did French government - more specifically Ministère de la culture et de la communication - approach even such mundane subject as the 404 page :-).\n","title":"Who said government's Web pages are boring ?","type":"post"},{"content":"It is all about deep questions and problems computer science. Including the question whether such thing as computer science actually exists. I thing it does, but have occasional moments of doubts - mostly when I read something related to real science :-).\nWhat does Andreas Zwinkau (it is read as ts-win-cow, my anglophone friends ;-)) think about it, can be found http://focs.wordpress.com/\nHis comments are amazingly deep for such a young guy. I wish when I was getting my comp-sci degree (1981-1986) we have had the same wonderful things these young fellas have now: ubiquitous internet and really world wide web with Google that actually makes it useful, Linux and many other wonderful open source projects (Apache, Jakarta, Firefox, Eclipse - you name it). Can you imagine studying computer science in a world where the Web does not exist (yet) ?\n","date":"October 5, 2007","externalUrl":null,"permalink":"/posts/2007-10-05-botd-figuring-out-computer-science/","section":"Posts","summary":"It is all about deep questions and problems computer science. Including the question whether such thing as computer science actually exists. I thing it does, but have occasional moments of doubts - mostly when I read something related to real science :-).\nWhat does Andreas Zwinkau (it is read as ts-win-cow, my anglophone friends ;-)) think about it, can be found http://focs.wordpress.com/\nHis comments are amazingly deep for such a young guy. I wish when I was getting my comp-sci degree (1981-1986) we have had the same wonderful things these young fellas have now: ubiquitous internet and really world wide web with Google that actually makes it useful, Linux and many other wonderful open source projects (Apache, Jakarta, Firefox, Eclipse - you name it). Can you imagine studying computer science in a world where the Web does not exist (yet) ?\n","title":"BOTD: Figuring out computer science","type":"post"},{"content":"Good selection of news, observations and comments on stuff that is happening around. There seems to be pretty good match between what Michael considers blogworthy and my areas of interest - as I found there lot of interesting pieces.\nIt is mostly news - but not only news. It is worth browsing through archive, just to discover small jewels - like this one:\nIf you had a top 7 tips list for managing the flood of digital information, what would it be?\nHere it is:\nWrite a blog. Of anything that I've done in the last 5 years, becoming habitual about writing a blog post almost daily has tremendously helped my information management. I no longer have a huge stack of \"interesting\" web links that I should / could / must look into sometime. It's all on my blog. If I want it in the future, I just Google my blog to find out what I know. Don't live in an email client. New messages are just \"one form of input\" (as David Allen likes to remind the world). Buy or build something for yourself that enables you to live from a list of projects and tasks. Look for the commonalities. Much of the guff that is written down is just a data point within a wider framework. Look for the commonalities within your area of focus, so that you can reason from general principles to particular situations. And if you already know something that you're reading, stop. Read more deep stuff. The majority of press releases, blog posts and news items are \"here today, gone tomorrow\". There's a sense that \"keeping up\" is good for you, but not always. Commit some of your reading and learning time to more classical texts and books that have stood the test of time. Get to know the key people who flood you with digital information. Knowing where they're coming from and from what mental models they view the world is tremendously helpful for understanding a specific item of digital information from them. If possible, do this in person or face-to-face. Build a personal knowledge management system. Build, use or maintain something that you can use to store articles, your analysis and critique thereof, and cross-references to other interesting and related items. Merely using Windows Explorer along with file name and date stamp is ABI (a bad idea). See the http://www.michaelsampson.net/2006/12/seven_things_de.html for #7.\n","date":"October 4, 2007","externalUrl":null,"permalink":"/posts/2007-10-04-botd-michaels-thoughts/","section":"Posts","summary":"Good selection of news, observations and comments on stuff that is happening around. There seems to be pretty good match between what Michael considers blogworthy and my areas of interest - as I found there lot of interesting pieces.\nIt is mostly news - but not only news. It is worth browsing through archive, just to discover small jewels - like this one:\nIf you had a top 7 tips list for managing the flood of digital information, what would it be?\n","title":"BOTD: Michael's Thoughts","type":"post"},{"content":"My current client is multi-national company, headquartered in Ottawa with offices in USA and Europe. With teams all over the globe, the conference calls and network meetings are part of the game. This usually means Microsoft Netmeeting to share the screen and teleconference bridge for voice. Netmeeting usually works quite OK - except when it does not - for no obvious reason :-).\nThanks to Yugma, there is now better alternative. Yugma is Sanskrit word meaning \"the state of being in unified collaboration\" and also a name of a startup, offering teleconferencing product that aspires to unify colaboration between platforms. And they mean it, because their product runs on Windows, Linux and Mac and integrates with Skype to take care of the voice portion.\nThe free version of the product offers teleconference up to 10 people (albeit it is unclear how that works with Skype which allows teleconference only up to 5 people), desktop sharing, desktop anotations and changing presenter during the session. The paid version in addition to accommodating larger teams (30, 50, 100 or 500 people) also allows keyboard and mouse remote access, session recording and replay, webcasts, filesharing and webinars (for the 500 version). The price of the premium service is very reasonable - the 30 user package costs about $30/month.\nWith products like this, I have every day less and less reasons not to switch to OS-X as main and only platform - running Windows XP and Linux in virtual machines to cover .NET and LAMP/NAMP stacks. It is coming :-)\n","date":"October 3, 2007","externalUrl":null,"permalink":"/posts/2007-10-03-like-netmeeting-only-much-better/","section":"Posts","summary":"My current client is multi-national company, headquartered in Ottawa with offices in USA and Europe. With teams all over the globe, the conference calls and network meetings are part of the game. This usually means Microsoft Netmeeting to share the screen and teleconference bridge for voice. Netmeeting usually works quite OK - except when it does not - for no obvious reason :-).\nThanks to Yugma, there is now better alternative. Yugma is Sanskrit word meaning \"the state of being in unified collaboration\" and also a name of a startup, offering teleconferencing product that aspires to unify colaboration between platforms. And they mean it, because their product runs on Windows, Linux and Mac and integrates with Skype to take care of the voice portion.\n","title":"Like Netmeeting - only much better","type":"post"},{"content":"For sixty more days (actually 59 days and 17 hours as of Time.now, or if you prefer to speak Javaish rather than Rubyish, new java.util.Date()) you will be able to download free PDF version of the book by Patrick Lenz Build Your Own Ruby on Rails Web Applications - courtesy of nice guys of Sitepoint.\nThe book download page is here, no strings attached - all it will cost you is disclosing an email address (book download link will be emailed to you) and bandwidth to get the 20 MB PDF. Mine is downloading right now, so I cannot tell anything about the book yet. It has 447 pages and from the table of content it looks like solid beginner's book.\nAs a nice surprise it covers Ruby installation under OS-X 10.5 (Leopard) :-). From the rumors I have heard, Leopard should come with Rails preinstalled and with current version of Ruby (1.8.6) - which will not stay current long because Ruby 1.9 as well as Rails 2.0 are quite close.\nSo hurry up and get your copy until Sitepoint's ISP does not disconnect them from excessive bandwidth usage :-). I am not joking, the first surge of download already did take down their server once :-).\nAfter you download - spread the word.\n","date":"October 2, 2007","externalUrl":null,"permalink":"/posts/2007-10-02-free-pdf-ebook-build-your-own-ruby-on-rails-application/","section":"Posts","summary":"For sixty more days (actually 59 days and 17 hours as of Time.now, or if you prefer to speak Javaish rather than Rubyish, new java.util.Date()) you will be able to download free PDF version of the book by Patrick Lenz Build Your Own Ruby on Rails Web Applications - courtesy of nice guys of Sitepoint.\nThe book download page is here, no strings attached - all it will cost you is disclosing an email address (book download link will be emailed to you) and bandwidth to get the 20 MB PDF. Mine is downloading right now, so I cannot tell anything about the book yet. It has 447 pages and from the table of content it looks like solid beginner's book.\n","title":"Free PDF ebook 'Build your own Ruby on Rails Application'","type":"post"},{"content":"There is - after all - a Petstore implementation for Ruby. Somebody asked a question at the DZone and the response posted by Raphael Valyi was:\nRe: Is there a Pet Store in Grails/Rails? I'm speaking here for the Rails (JRuby) side:\nthere is actually a petstore, it can be found there:\nhttp://viewvc.rubyforge.mmmultiworks.com/cgi/viewvc.cgi/?root=tw-commons\nSome guys used it to compare C-Ruby vs JRuby performance:\nhttp://www.nabble.com/JRuby-vs-MRI---Petstore-shootout-t4289470.html\n","date":"October 1, 2007","externalUrl":null,"permalink":"/posts/2007-10-01-petstore-for-rubyjruby/","section":"Posts","summary":"There is - after all - a Petstore implementation for Ruby. Somebody asked a question at the DZone and the response posted by Raphael Valyi was:\nRe: Is there a Pet Store in Grails/Rails? I'm speaking here for the Rails (JRuby) side:\nthere is actually a petstore, it can be found there:\nhttp://viewvc.rubyforge.mmmultiworks.com/cgi/viewvc.cgi/?root=tw-commons\nSome guys used it to compare C-Ruby vs JRuby performance:\nhttp://www.nabble.com/JRuby-vs-MRI---Petstore-shootout-t4289470.html\n","title":"Petstore for Ruby/JRuby","type":"post"},{"content":"According to the TIOBE Programming Community index (which gives an indication of the popularity of programming languages), Ruby jumped 3 places and made it to top ten. Congratulations !\nIf you look closely on the trends down on the page, the dynamically languages popularity has risen over 3.6% during year period. Which is A Good Thing (TM).\nShould I make my personal Top Ten of the programming languages, ordering languages by my degree of comfort of using the language, the language beauty (which is, in the eye of the beholder ;-)). Factoring in also how much I do enjoy reading/writing code in that language and it's usefulness from both personal as well professional point of view, the index would look like this:\nJava C# Ruby SQL (both T/SQL and PL/SQL) Javascript Objective-C Python Shells (mostly BASH) Perl VB.NET First place is practically tie - as the Java / C# are in reality more two dialects than two languages. They were very close at the beginning and with latest versions (C# 2.0, Java 5) they got even close. As it looks like, in the future they may diverge more with all the LINQ stuff coming in C# 3.0. I like Java portability, amazing variety of open source code available - and the development tools are IMHO still better on Java side (Eclipse, IDEA, Netbeans), but C# syntax of properties is nicer and there are slightly more commercial opportunities with Microsoft platform (at least during last 3-4 years).\nThe only \"real\" compiled language in my list is Objective-C, for which I have absolutely no commercial use for right now, but I hope that will change one day when the greatest of all cats finally arrives. Neither C or C++ made the list - the only encounters with C these days are during installations of Ruby GEM on Linux or Mac platform - which often comes with native part in C source - and the installer barfs at me with some gcc error :-). And despite using Mac for over a year now, I felt no need to write anything bigger than Hello World in AppleScript\n","date":"September 30, 2007","externalUrl":null,"permalink":"/posts/2007-09-30-ruby-is-in-top-ten-programming-languages/","section":"Posts","summary":"According to the TIOBE Programming Community index (which gives an indication of the popularity of programming languages), Ruby jumped 3 places and made it to top ten. Congratulations !\nIf you look closely on the trends down on the page, the dynamically languages popularity has risen over 3.6% during year period. Which is A Good Thing (TM).\nShould I make my personal Top Ten of the programming languages, ordering languages by my degree of comfort of using the language, the language beauty (which is, in the eye of the beholder ;-)). Factoring in also how much I do enjoy reading/writing code in that language and it's usefulness from both personal as well professional point of view, the index would look like this:\n","title":"Ruby is in top ten programming languages","type":"post"},{"content":"","date":"September 27, 2007","externalUrl":null,"permalink":"/tags/dot-net/","section":"Tags","summary":"","title":"Dot-Net","type":"tags"},{"content":"From Scott Guthrie's interview on .NET futures\nSG: We’ve seen demand for an MVC framework on two fronts. One is for even more testability, having the ability to completely mock-up a request. We’ve also always seen with ASP.NET that some people like having the server control, postback model; some people say, “I just want absolute control.”\nThe MVC framework we’re coming up with is a fairly simple MVC model, it’s very clean, it’s a front controller model, and it integrates very well into ASP.NET so you can use ASP.NET forms authentication, session state, security, personalisation, caching, all the standard features, but with an alternative to the postback model where you have a more traditional controller-view separation and have complete control over your HTML.\nThe other thing is that for the view, you can use .aspx templates, master pages and all the Visual Studio tool features. It integrates nicely into ASP.NET and preserves everyone’s investment. You can have a single app that has both pages built with MVC and pages built with postback. People can choose.\nSee http://www.itwriting.com/blog/?page_id=329\nFinally - if that happens, maybe next time when I will be crossing the platform boundaries going back from Java and Spring to ASP.NET on the next project, I will not have that old feeling as in 2005: yes, this ASP.NET thing works, one can build pretty decent application in it and is not really so bad after you get used to it - but is still sooo inflexible and limiting compared to the beauty and simplicity of Spring MVC, or Webmacro.\nLooking forward :-)\n","date":"September 27, 2007","externalUrl":null,"permalink":"/posts/2007-09-27-microsoft-will-ship-mvc-for-aspnet/","section":"Posts","summary":"From Scott Guthrie's interview on .NET futures\nSG: We’ve seen demand for an MVC framework on two fronts. One is for even more testability, having the ability to completely mock-up a request. We’ve also always seen with ASP.NET that some people like having the server control, postback model; some people say, “I just want absolute control.”\nThe MVC framework we’re coming up with is a fairly simple MVC model, it’s very clean, it’s a front controller model, and it integrates very well into ASP.NET so you can use ASP.NET forms authentication, session state, security, personalisation, caching, all the standard features, but with an alternative to the postback model where you have a more traditional controller-view separation and have complete control over your HTML.\n","title":"Microsoft will ship MVC for ASP.NET ?","type":"post"},{"content":"If you live on week cycles, it is quite nice to see the week number in your calendar. It is not (yet) provided as standard feature in the user settings for my calendar solution of choice.\nAn obvious solution is to run user script in the browser that will decorate the calendar page - using the fabulous Grease Monkey. The user script to install (after installing the plugin) is here.\nIt works, but ... However I admire the power and possibilities of the user-scripts, it is fairly heavy tool for such simple thing. My Firefox install is pretty large thanks to variety of developer-oriented plugins, and I do not want to slow it down even more. Another issue with scripts is potential security implication - recently (as you will see on the script site) a malicious user started to upload scripts stealing cookies. What this means for slightly paranoid security-aware person like me, is to read and understand the source - and that is way too much trouble.\nFortunately, there is better solution using Google API's - you just subscribe to a calendar that has the information :-). Simple, elegant and as secure as the calendar itself :-) - all you have to do is to click on this link (for weeks starting on Sunday).\nThe page for the non-greasy solution is http://recover89.googlepages.com/googlecalendarweeknumbers - it contains link for Monday based weeks as well.\n","date":"September 26, 2007","externalUrl":null,"permalink":"/posts/2007-09-26-adding-week-numbers-to-google-calendar/","section":"Posts","summary":"If you live on week cycles, it is quite nice to see the week number in your calendar. It is not (yet) provided as standard feature in the user settings for my calendar solution of choice.\nAn obvious solution is to run user script in the browser that will decorate the calendar page - using the fabulous Grease Monkey. The user script to install (after installing the plugin) is here.\nIt works, but ... However I admire the power and possibilities of the user-scripts, it is fairly heavy tool for such simple thing. My Firefox install is pretty large thanks to variety of developer-oriented plugins, and I do not want to slow it down even more. Another issue with scripts is potential security implication - recently (as you will see on the script site) a malicious user started to upload scripts stealing cookies. What this means for slightly paranoid security-aware person like me, is to read and understand the source - and that is way too much trouble.\n","title":"Adding week numbers to Google Calendar","type":"post"},{"content":"Experience is what you get when you did not get what you wanted.\nBrick walls are there for a reason: they let us prove how badly we want things.\nThey are there to stop the people who do not want it badly enough\nThey are there to stop \"the other people\"\nRandy Pausch If you want to watch and listen to a lecture by professor of CMU Computer Science that will teach you things way beyond realms of software engineering, check this video.\nIt is long - over 1:45 hour, but worth every minute. It will make you stop and think ....\n","date":"September 25, 2007","externalUrl":null,"permalink":"/posts/2007-09-25-quote-of-the-day-11/","section":"Posts","summary":"Experience is what you get when you did not get what you wanted.\nBrick walls are there for a reason: they let us prove how badly we want things.\nThey are there to stop the people who do not want it badly enough\nThey are there to stop \"the other people\"\nRandy Pausch If you want to watch and listen to a lecture by professor of CMU Computer Science that will teach you things way beyond realms of software engineering, check this video.\n","title":"Quote of the day","type":"post"},{"content":"As part of current project I need to test some ORM frameworks and for that, you need a database. In this particular case, database equals Oracle. I need a local instance to be able to work outside of the customer's location.\nOn my notebook, I have already installation of MySQL (for all the Rails stuff) and SQLServer (for ASP.NET). Plus few lightweight databases (meaning that they do not really need a server) such as sqlite3, Derby and HSQLDB). I was very hesitant to add another instance and for some time tried to do the work with MySQL - but differences in SQL and most importantly the way how the CLOBs and BLOBs are handled convinced me this is a bad idea.\nSo grudgingly I downloaded the Oracle 10g Express Edition - which is free and available for any use - including production deployment. Remembering my last installation was not very encouraging: the machine I installed the 9i suite (Windows 2000 back in 2002 or 2003) became close to unusable for development after install because of the memory consumption and CPU load of the database server - and after the installation I had to go and develop on different machine. I also remembered that it installed variety of services, two or three different instances of Apache (for no obvious reason) and lots of other stuff I had no need for.\nI have to say that Oracle made a huge improvement since that time. The install went very smooth, did not mess up the notebook and everything actually works very nicely. It did not even ask the scary questions that one does not fully understand and later pay dearly for answering them wrong... The admin interface is web based and does not require you to read hundreds pages of documentation to make anything useful. It shows memory used and allows easily manage users, databases and pretty much everything what a developer (not a DBA) may want. If you need more or are an Oracle DBA, you have the dreaded command line based SQL tool available as well - so even Bob can feel at home with XE :-). The whole Oracle suite is now single service (more or less) and if you do not need it, you just stop single service (shortcut in Programs is provided) and claim the memory + CPU to where you need them.\nNow I know that if you need a lightweight commercial grade database (backed with The Big Name), there is an alternative to SQL Server Express - very comparable with respect to footprint, resources, easy of use and limitations (from developer's point of view unimportant such as 4 GB size limit on database). And as added benefit, you can install on Windows or Linux - which may come handy if you need to build a virtual database appliance without any licensing issues on the operating system side ...\n","date":"September 24, 2007","externalUrl":null,"permalink":"/posts/2007-09-24-oracle-10g-xe-nice-surprise/","section":"Posts","summary":"As part of current project I need to test some ORM frameworks and for that, you need a database. In this particular case, database equals Oracle. I need a local instance to be able to work outside of the customer's location.\nOn my notebook, I have already installation of MySQL (for all the Rails stuff) and SQLServer (for ASP.NET). Plus few lightweight databases (meaning that they do not really need a server) such as sqlite3, Derby and HSQLDB). I was very hesitant to add another instance and for some time tried to do the work with MySQL - but differences in SQL and most importantly the way how the CLOBs and BLOBs are handled convinced me this is a bad idea.\n","title":"Oracle 10g XE - nice surprise","type":"post"},{"content":"This is blog entry I wrote over a two years ago - before this blog has even started. Now I found it on the disk during cleanups and found out it is still valid. The iPod mentioned was my first, now long dead first generation Shuffle.\nHere it comes:\nSpent most of Friday night and part of Saturday reading this book. I did not really expect to finish it, considering the size (~ 500 pages) and the fact that I am not such a great fan of Oracle products - especially not the Oracle Apps. But it turned up to be way better that expected. I mean the book, albeit I partially improved my opinion about the 11i. Technologywise, it is still kind a dinosaur, but now I can more appreciate the sheer size of the problem these guys were trying to address. But back to the book.\nThe author IMHO did a pretty good job being fair observer. On almost each page, there are comments and notes written by Larry Ellison, which often provide a view from the alternate reality. That was the best part. All summed up, I learned a lot. I did not know before that many of the dot-com eBusiness big names such as Ariba, i2, Siebel were actually founded and run by ex-Oracle employees, usually senior sales folks (e.g. Tom Siebel). Understanding the history of Oracle, from first commercial non-mainframe relational, database through applications up to latest entrance into J2EE world with licensing Orion and making it OC4J, was very illuminating and I quite enjoyed it.\nThis guy (I mean LE, not the author) is really interesting and definitely smart. Not exactly that type of personality I would enjoy spending a lot of time with, but certainly somebody you will not forget. I did not know about the yachts, 40 acre house with artificial, earthquake-resistant 5 acre lake and a Zen garden. Some people indulge themselves with toys such as iPods and notebooks, some with 300 foot yachts and jet fighters. I hope that Larry enjoyed them as much as I my iPod :-).\nSome of the Larry's comments are really funny:\n\"People regularly mistake obedience for intelligence. That's why we think that dogs are more intelligent than cats. .. A dog will fetch a stick every time you throw it. A cat will look at you and wonder: If you wanted the stick, why did you throw it away in a first place? Get it yourself, idiot.\" (page 335)\n","date":"September 23, 2007","externalUrl":null,"permalink":"/posts/2007-09-23-book-softwar-an-intimate-portrait-of-larry-ellison-and-oracle/","section":"Posts","summary":"This is blog entry I wrote over a two years ago - before this blog has even started. Now I found it on the disk during cleanups and found out it is still valid. The iPod mentioned was my first, now long dead first generation Shuffle.\nHere it comes:\nSpent most of Friday night and part of Saturday reading this book. I did not really expect to finish it, considering the size (~ 500 pages) and the fact that I am not such a great fan of Oracle products - especially not the Oracle Apps. But it turned up to be way better that expected. I mean the book, albeit I partially improved my opinion about the 11i. Technologywise, it is still kind a dinosaur, but now I can more appreciate the sheer size of the problem these guys were trying to address. But back to the book.\n","title":"Book: Softwar - an intimate portrait of Larry Ellison and Oracle","type":"post"},{"content":"Today's Blog of the Day is \"The Reader\".\nEverything about ebooks and readers - all the stuff I like. See at http://wowio.wordpress.com/\nHere I discovered that Sony is assumably preparing new version of reader - PRS 505. From the changes that should be included, none is IMHO really so important. The memory capacity of the reader with SD cards (which are reaching 8GB these days) is much bigger than you ever will need. If I should pick some enhancements hat would make a huge difference, it would be:\n1) price. Make it accessible, meaning ~ 150 USD (which is about 145 CAD :-) - just kidding)\n2) content - price and availability of books. The fair price for eBook should not be more than 30-40% of the paperback. Without DRM, of course. Who would want any DRM from the company with 2 rootkit fiasco's in last 2 years (first and second) ?\n3) Software - Sony please stop trying to create these terrible slow knock-off of iTunes, and outsource it to somebody that will write decent client, preferably in Java, so that it runs everywhere. Considering Sony's software history, making it opensource would help to restore the trust ...\nSpeaking of software, it should provide an easy way how to download and format RSS feed and web pages for offline reading, ideally again something in the way how iTunes handles podcasts.\nI do not think that adding WiFi (what many people call for) will work on the eInk device - speed and lack of interactivity would allow to read only very static Web pages, and user input handling would be a big challenge.\n","date":"September 22, 2007","externalUrl":null,"permalink":"/posts/2007-09-22-botd-the-reader/","section":"Posts","summary":"Today's Blog of the Day is \"The Reader\".\nEverything about ebooks and readers - all the stuff I like. See at http://wowio.wordpress.com/\nHere I discovered that Sony is assumably preparing new version of reader - PRS 505. From the changes that should be included, none is IMHO really so important. The memory capacity of the reader with SD cards (which are reaching 8GB these days) is much bigger than you ever will need. If I should pick some enhancements hat would make a huge difference, it would be:\n","title":"BOTD: The Reader","type":"post"},{"content":"Few nuggets from recent surfing and reading newsfeeds:\nA very nice explanation of differences between Ruby Gem and Rails plugin in Arun Gupta's blog\nThe community seems to be still fairly divided on the \"Is Vista good or bad\" ? For the laters, read the story from the corporate IT point of view. I still have not found any good reason to upgrade :-).\nGood story of how the experience of joining a project should not look like\nGood discussion on Flex, Flash\nLong but interesting blogpost on ontology\nMySQL seen from the point of view of experienced SQL Server user\nSome news from the GooglePlex: everybody seems to notice that Google added the presentations to spreadsheets and documents, so you have now complete simple but functional replacements of the Word, Excel and Powerpoint for free. Google also stepped again into territory of social bookmarking - after Google bookmarks they are launching Shared Stuff. The news I personally liked the most is writeable API to GData.\nListing of hundred tools for Semantic Web\n","date":"September 21, 2007","externalUrl":null,"permalink":"/posts/2007-09-21-webbits-2007-06-2/","section":"Posts","summary":"Few nuggets from recent surfing and reading newsfeeds:\nA very nice explanation of differences between Ruby Gem and Rails plugin in Arun Gupta's blog\nThe community seems to be still fairly divided on the \"Is Vista good or bad\" ? For the laters, read the story from the corporate IT point of view. I still have not found any good reason to upgrade :-).\nGood story of how the experience of joining a project should not look like\n","title":"Webbits 2007-06","type":"post"},{"content":"If you try to deploy one of the Spring 2 samples included in the Spring framework source distribution - Petclinic on Tomcat 6 (6.0.14), the web application does not get loaded and fails with errror. The cause is the ClassNotFound exception for the class org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader, more precisely:\nSEVERE: LifecycleException\njava.lang.ClassNotFoundException: org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader\nat java.net.URLClassLoader$1.run(Unknown Source)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.net.URLClassLoader.findClass(Unknown Source)\nat java.lang.ClassLoader.loadClass(Unknown Source)\nThe message is a bit confusing, because after peeking into spring.jar you'll find out that class in question is it is contained in the jar. What is happening is \"classical\" issue of classloaders and the who-loads-what problem.\nFortunately, solution is very easy: what helped was copying the spring-tomcat-weaver.jar from Spring distribution into TOMCAT_HOME/lib directory and restarting the container.\nThis thread was helpful to find out the cause. It may also be mentioned in the documentation, alas - I did not get to reading it yet :-).\n","date":"September 20, 2007","externalUrl":null,"permalink":"/posts/2007-09-20-spring-example-petclinic-on-tomcat-6/","section":"Posts","summary":"If you try to deploy one of the Spring 2 samples included in the Spring framework source distribution - Petclinic on Tomcat 6 (6.0.14), the web application does not get loaded and fails with errror. The cause is the ClassNotFound exception for the class org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader, more precisely:\nSEVERE: LifecycleException\njava.lang.ClassNotFoundException: org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader\nat java.net.URLClassLoader$1.run(Unknown Source)\nat java.security.AccessController.doPrivileged(Native Method)\nat java.net.URLClassLoader.findClass(Unknown Source)\nat java.lang.ClassLoader.loadClass(Unknown Source)\n","title":"Spring example Petclinic on Tomcat 6","type":"post"},{"content":"After returning from holidays with completely drained PRS 500 (see field test blog entry), I have decided to test what is the battery life of the fully charged reader without any usage at all. It was easy as I was pretty busy after being away 3 weeks.\nThe reader was fully charged on 29th of August (24 hrs with wall charger). After that, I did not use it at all, only checked every 2-3 days the status (the reader was switched off except this brief check). As of Wednesday morning, September 19th the battery was drained and the reader switched itself off right away (it is being charged as I type this). This gives us about 3 weeks of available standby time, without any use from page turning, until the fully charged battery is completely drained.\nThis result allows new angle in looking into the \"7500 pageturns story\". Let's assume that the battery indeed lasts for 7500 turns and let's factor in the consumption of standby. When the reader is off, every week will take away about one third of the charge - or in other words you will loose battery capacity equivalent to 2500 page turns a week regardless whether you switch it on or not.\nIf you would turn page every 2 secs, 30 pages a minute, 1800 pages an hour, chances are that you might get closer to the ideal capacity. But if you read a book with a speed of 200 pages per hour (these are small pages) and have have time to read 2 hours a day, during you will \"spend\" about 7 x 2 x 200 = 2800 page turns - plus the weekly standby tax of 2500 page turns. With this, you will have available about 2200 turns - or less than a week in standby and if you will continue to read, you will have to recharge in about 9-10 days. Which is quite consistent with what I have seen o vacation: the reader died after two and half week (~ 6000 turns) plus about 1500 real pages.\nSo, the 7500 turns may not be such an impossible number - if you can read 1000+ pages an hour :-).\nWith the size of the screen, depending on the font and real page count books are anywhere between 500 and 1500 turns long. That means, one full charge is realistically good for 3-4 books.\n","date":"September 19, 2007","externalUrl":null,"permalink":"/posts/2007-09-19-experiment-with-sony-reader-battery-life/","section":"Posts","summary":"After returning from holidays with completely drained PRS 500 (see field test blog entry), I have decided to test what is the battery life of the fully charged reader without any usage at all. It was easy as I was pretty busy after being away 3 weeks.\nThe reader was fully charged on 29th of August (24 hrs with wall charger). After that, I did not use it at all, only checked every 2-3 days the status (the reader was switched off except this brief check). As of Wednesday morning, September 19th the battery was drained and the reader switched itself off right away (it is being charged as I type this). This gives us about 3 weeks of available standby time, without any use from page turning, until the fully charged battery is completely drained.\n","title":"Experiment with Sony Reader battery life","type":"post"},{"content":"Part of the technology upgrade in the three Java based projects is also tool update. We have started with Eclipse version 1 and gradually moved up to the currently used Eclipse 3.0. The build and deployment process was based on custom written Ant build script, which compiled, created WAR, deployed, undeployed, run the tests, created source snapshot - you name it. The Eclipse was used mostly as editor and debugger - using JPDA talking to Tomcat started in debug mode.\nThat worked pretty much fine and there is no real need to fix it. The process was a bit work intensive - as you had most of time redeploy the WAR file, which (in most cases) required shutdown and restart of Tomcat (we have started back with Tomcat 3.x and the reloadable WAR's came later).\nSince that time, technologies evolved, we have now Eclipse 3.3 aka Europa with Web Tool Projects that promises usable editor for JSP, XML, integration with application servers and many other improvements. back in Eclipse 3.x time we used the commercial extensions MyEclipseIDE to achieve that - without it, the JSP and XML would be just plain text file without even colorization.\nTo be up to date, we want to use current Eclipse, so I gave 3.3 with WTP (Web Tools Project) a try. It works, but .... I mean - if you start developing new Web project from scratch, everything is fine: you can define app server configuration, Eclipse synchronizes the deployed WAR as soon as you change anything and you can debug - placing breakpoints. Sometimes (and actually quite often) it wants to restart the server - but I have not found any issues with WTP and was quite impressed with how things evolved.\nThe troubles begins if you have existing Web application that you need to somehow get into Eclipse WTP and do not want to change your structure to what Eclipse considers to be the Dynamic Web project. I have not found easy and obvious way how to load existing sources and tell the system: this is my Web application, here is the Web folder (and it is named war, not WebContent), here are the libraries I want you to put into WEB-INF/lib and so on. Or at least - here is my Ant file, use this task to build WAR and deploy it to that server. Chances are it is possible if you spend enough time digging deeper - but I had no time doing that.\nInfluenced by the very nice experience with Netbeans-based Ruby development, I also tried the Beta1 of Netbeans 6. On the positive side, it was noticeably more responsive and faster on my battered Fujitsu notebook than Eclipse 3.3. It seemed also more flexible when it came to working with existing structure. I had to rename existing build directory, as it wanted to use it - and it prompted for different Ant file name (having found existing build.xml). Generated build file was pretty intense - filled with looots of targets named as callbacks - (pre_build_something, build_something, post_build_something). I managed to get further that with WTP but what was a showstopper was an error in communicating with Tomcat (6.0.14). After configuring server, Netbeans starts it but never gets any information that the Tomcat is indeen running (which it was). As result, you cannot stop it, and next deploy will try start another Tomcat and die on port conflicts. It is Beta1, and possibly it may be a my machine configuration issue - but that was it, Netbeans was not the solution.\nOne thing that I did not appreciate about the Netbeans that it silently placed two JAR's into my Tomcat's lib directory. I use the server with or without dev environment, so messing with the classes loaded is not a great idea, guys ! The files are easy to recognize - the names have the format org_netbeans_SOMETHING.jar. Actually, I ended up deleting and reinstalling Tomcat to make sure there are no hidden changes.\nLast attempt was getting back to MyEclipseIDE, which worked for us back then so well. As a matter of fact, it was so great that in 2005 I have purchased licenses for the whole team from my own pocket, just to be able to use it on the project (after finding out that to get approval from government department my team members worked for to expense the huge amount 3 times 29 CAD would require four meetings and seven signatures :-)).\nThe MyEclipseIDE is now in version 6.0GA (general availability), specially for the version 3.3 of Eclipse. I downloaded again the Eclipse core 3.3 release and did manual install of MyEclipseIDE (== MEI). The guys at Genuitech - company behind MEI got it right: to make a an existing project a Web project, you simply add to it a Web project nature - same way as you can add it Spring nature, JSTL nature etc. It is very intuitive and very obvious.\nAfter doing this, I was able to create the Web project in existing source tree, configure it, define where is what and define deployment of one of the many servers and bang - it worked. I was able to edit JSP, place breakpoint into scriplet, and step through it.\nThere is much more in the MEI - visual designers for JSP and JSF, database inspector, - most of which I do not need and do not really care about, but the convenience of working with existing legacy code without changing structure and user comfort on the core developers tasks is IMHO well worth $49.\nSo final score: WTP project is very nice and does the job if you have the luxury start from scratch, but for real world, MyEclipse still leads the pack :-).\n","date":"September 18, 2007","externalUrl":null,"permalink":"/posts/2007-09-18-java-web-tools-eclipse-wtp-netbeans-and-myeclipse/","section":"Posts","summary":"Part of the technology upgrade in the three Java based projects is also tool update. We have started with Eclipse version 1 and gradually moved up to the currently used Eclipse 3.0. The build and deployment process was based on custom written Ant build script, which compiled, created WAR, deployed, undeployed, run the tests, created source snapshot - you name it. The Eclipse was used mostly as editor and debugger - using JPDA talking to Tomcat started in debug mode.\n","title":"Java Web tools: Eclipse WTP, Netbeans and MyEclipse","type":"post"},{"content":"One of the many gadgets I have packed for the summer vacation was of course Sony Reader and SD card with nice selection of texts. It was fresh and fully charged, so I assumed that I will be well prepared for the gaps in program during the following three weeks ahead of us and for the long flights over Atlantic.\nObviously, the flight was first moment where Reader was used. During the 7 hours, I spent about 3-4 hours reading. We flew through the night, but the overhead spotlight in airplane was more than sufficient and the letters were very well readable. I also enjoyed the almost non-reflexive surface of the screen.\nAs we were traveling, I did not read much during first week - maybe 4-5 hours in total. Where I really had some leisure time and used it again was Siena (by the swimming pool) and a bit on beach in Tirrenia and Lido di Ostia. For these light conditions, the Reader is probably only electronic device usable - it is perfectly readable in direct sunlight. Few years ago I tried to read during vacation outdoors on Pocket PC - with very dismal results.\nAs the trip was coming towards the end, so was the battery indicator on the PRS 500. No way I have made 7500 page turns - altogether, it could have been 1000-1500 pages, with some menu searching certainly not more than 2000 turns. The reader was on for about 20 hours (which should not count as it is not supposed to consume any energy in on state). During the two and half weeks and less than 2000 turns the battery was on single bar of four.\nFoolishly enough, I have not packed the charger, relying on 3000-4000 pages capacity. What a mistake. I had plan B - using USB cable and charging through computer. I had with me Macbook - without Sony Connect software (which is available in Sony's tradition for Windows only) - but I assumed that to charge all I need is powered USB port. Mistake number two - it did not work.\nWhat happened was quite weird - the power indicator actually jumped to full after connecting, and stayed there while connected, but it looked like the computer actually drained the battery. After few hours I disconnected the reader, turned it on - and screen went blank. After reconnecting it to USB, it showed the cable indicator, but did not really charge - even when left attached overnight. As result, I was flying back without access to my ebooks. At home, after full recharge from the adapter, it behaved perfectly OK.\nI am not sure whether this means that Reader really must be charged only by the wall charger - or whether the USB ports in Macbook did not have enough power for charge. I think I saw the charging via USB work before - but it was my Fujitsu Lifebook, which has the Connect installed. More experiments pending :-)\nFortunately, we were well equipped and bringing back one suitcase full of boks purchased in my favorite Bratislava bookstore - so I survived :-).\nLessons learned:\n1) do not trust Sony's marketing. The 7500 page turns is an urban legend. I have reader for 8 months now and NEVER came even close to half of that number.\n2) Always bring the charger - the battery will discharge even with very light use during 2-3 weeks.\n3) Reader is best thing to have for outdoor, bright environments. Reading in limited, artificial light conditions is not so great - but workable. Overhead spotlight in airplane works fine.\n4) Reader is good for about 20-25 hours and around 1500-2000 page turns without charge.\nIt is still not bad - I have no other device running for more than 4-5 hours without needing a recharge - but quite a disappointment with respect to the high expectations.\n","date":"September 17, 2007","externalUrl":null,"permalink":"/posts/2007-09-17-field-test-of-sony-ereader/","section":"Posts","summary":"One of the many gadgets I have packed for the summer vacation was of course Sony Reader and SD card with nice selection of texts. It was fresh and fully charged, so I assumed that I will be well prepared for the gaps in program during the following three weeks ahead of us and for the long flights over Atlantic.\nObviously, the flight was first moment where Reader was used. During the 7 hours, I spent about 3-4 hours reading. We flew through the night, but the overhead spotlight in airplane was more than sufficient and the letters were very well readable. I also enjoyed the almost non-reflexive surface of the screen.\n","title":"Field test of Sony eReader","type":"post"},{"content":"The combination of software allowing anonymous access to the Net, not too competent police officers and laws not quite 21st century ready can be a very dangerous combination. According this story, the operator of the Tor node was arrested by German police ...\nI am quite curious how be would situation like this handled in Canada. First of all, would it happen ? Would the RCMP be more technically up to date than Deutsche Polizei ? What defines the responsibility of an operator of server, that moves encrypted content ? I am not crazy enough to try it out just to find out :-) - so no, I will not setup a TOR node (even if I do admire this cleverly designed piece of software).\nSometimes volunteering in a not-for-profit case may cost you a lot - as Alex Janssen found out the hard way:\nI was arrested. They scared my wife. They confiscated all my equipment. They stopped the investigation. I’m sitting on a pile of bills from my lawyer no one except me has to pay. I’ll sue for compensation, but I don’t think that this will lead anywhere.\nWhat happened to \"innocent until proven guilty\" ? Is there anything one can do to help stop traps like this ?\nActually, there is. Spread the word.\n","date":"September 17, 2007","externalUrl":null,"permalink":"/posts/2007-09-17-the-price-of-anonymity/","section":"Posts","summary":"The combination of software allowing anonymous access to the Net, not too competent police officers and laws not quite 21st century ready can be a very dangerous combination. According this story, the operator of the Tor node was arrested by German police ...\nI am quite curious how be would situation like this handled in Canada. First of all, would it happen ? Would the RCMP be more technically up to date than Deutsche Polizei ? What defines the responsibility of an operator of server, that moves encrypted content ? I am not crazy enough to try it out just to find out :-) - so no, I will not setup a TOR node (even if I do admire this cleverly designed piece of software).\n","title":"The price of anonymity","type":"post"},{"content":"First-rate people hire first-rate people; second-rate people hire third-rate people.\nLeo Rosten\n","date":"September 16, 2007","externalUrl":null,"permalink":"/posts/2007-09-16-quote-of-the-day-10/","section":"Posts","summary":"First-rate people hire first-rate people; second-rate people hire third-rate people.\nLeo Rosten\n","title":"Quote of the day","type":"post"},{"content":"Today's BOTD (Blog of the Day) is \"Good Math, Bad math\".\nWhat it is about is summarized in its subtitle:\nFinding the fun in good math. Squashing the bad math and the fools who promote it. There is no need to add anything to this.\nOnly maybe an URL: http://scienceblogs.com/goodmath/\n","date":"September 14, 2007","externalUrl":null,"permalink":"/posts/2007-09-14-botd-good-math-bad-math/","section":"Posts","summary":"Today's BOTD (Blog of the Day) is \"Good Math, Bad math\".\nWhat it is about is summarized in its subtitle:\nFinding the fun in good math. Squashing the bad math and the fools who promote it. There is no need to add anything to this.\nOnly maybe an URL: http://scienceblogs.com/goodmath/\n","title":"BOTD: Good Math, Bad Math","type":"post"},{"content":"For those of you who asked: I started to put up some images from Europe 2007 trip on Smugmug. Small subset of course (total amount with NEFs is almost 20 GB).\nI will upload more as I get to weeding them out :-).\n","date":"September 13, 2007","externalUrl":null,"permalink":"/posts/2007-09-13-images-from-vacation-are-on-smugmug/","section":"Posts","summary":"For those of you who asked: I started to put up some images from Europe 2007 trip on Smugmug. Small subset of course (total amount with NEFs is almost 20 GB).\nI will upload more as I get to weeding them out :-).\n","title":"Images from vacation are on Smugmug","type":"post"},{"content":"Software problems aren't like mathematical problems. They have no clear boundaries or axioms and the problem domain is always shifting and evolving and changing. This fundamental difference ensures that while mathematical knowledge has a long shelf life, technical knowledge seems to last little longer than most popstars. And the changes wrought in programming are not just shallow refinements or surface innovations but fundamental changes wrought by order-of-magnitude shifts in the virtual landscape.\nFrom http://blogs.concedere.net:8080/blog/discipline/software+engineering/?permalink=The-Problematic-Nature-of-Problems.html\n","date":"September 13, 2007","externalUrl":null,"permalink":"/posts/2007-09-13-quote-of-the-day-9/","section":"Posts","summary":"Software problems aren't like mathematical problems. They have no clear boundaries or axioms and the problem domain is always shifting and evolving and changing. This fundamental difference ensures that while mathematical knowledge has a long shelf life, technical knowledge seems to last little longer than most popstars. And the changes wrought in programming are not just shallow refinements or surface innovations but fundamental changes wrought by order-of-magnitude shifts in the virtual landscape.\n","title":"Quote of the day","type":"post"},{"content":"During my recent return to Javaland, I have noticed many improvements in newer releases of well established frameworks and toolkits, as well as many new ones. One such new release is version 2 of Spring framework. It is not really a hot news, because the final version of 2.0 is out for almost a year (October 2006), but it is new to me, because I spend pretty much all of last 12 months in DotNet, C# and OLAP worlds, with only brief visits to older Struts based, Spring-free Java projects.\nSpring has an excellent documentation and great API comments, so after one gets over mental switch to IoC and AOP, there is not really strong need for reading anything else except source and documentation, bar saving some time. But because this books title - Building Spring 2 Enterprise applications - explicitly mentioned version 2 of the framework and because of Joel's intriquing remark on how Spring 2 configuration extensions reminds him of good old ATG Dynamo, I purchased PDF version of the book from the Apress.\nI am not quite done with the book yet, but I like what I have read so far. The chapter on AOP is probably one of the clearest explanations of benefits and principles of aspect oriented programming and differences against object oriented design. If you have chaos in the pointcuts, advices, advisors, aspects and join points, the chapters 3 and 4 are alone worth of $25 spent on the ebook.\nChapters 5 and 6 are dealing with data access and cover in detail using Spring JDBC helpers and extensions, that allow write clean, condense database code without worrying about pooling, connection management, resource management and cleanup and exception handling. It does not cover the alternative methods such as ORM (Hibernate, JDO) or iBatis.\nThere is one major problem with the book, that hopefully will be fixed soon: the book asks you to download the source code for the sample from the Apress site - and the site does not provide any source download. I have contacted the Apress tech support and got response that the authors of the book did not provide the code yet.\nWithout the code, the coolest feature of the programming books - instant gratification from building and running sample and then enjoying the beauty of design and discovering \"how did the do it\" - is lost. Even if you had time and patience to type in the examples, you could not, because the book contains only subset of the code (and rightly so). So I can only hope that the authors - Seth Ladd or Bram Smeets - will get in touch with Apress and fix it soon ...\nUpdate: as of Monday, Sept 24th, the source code is available for download.\n","date":"September 12, 2007","externalUrl":null,"permalink":"/posts/2007-09-12-good-book-on-spring-framework-version-2/","section":"Posts","summary":"During my recent return to Javaland, I have noticed many improvements in newer releases of well established frameworks and toolkits, as well as many new ones. One such new release is version 2 of Spring framework. It is not really a hot news, because the final version of 2.0 is out for almost a year (October 2006), but it is new to me, because I spend pretty much all of last 12 months in DotNet, C# and OLAP worlds, with only brief visits to older Struts based, Spring-free Java projects.\n","title":"Good book on Spring Framework version 2","type":"post"},{"content":"As the September 28th is approaching (the day when the new iPod touch will be available in Canada), I have a real dilemma: do I go with the \"iPhone without the phone\" or not ? The price $329 for 8 GB iPod is pretty high - compared to $279 for 80GB classic - which would allow me to carry all my music, some movies and all podcasts with me. On the other hand, the Touch has WiFi and can be used as pretty decent Web browser on top of iPod functionality.\nWhat will be the decision point for me is probably how good or bad is this device for reading eBooks - as I am real eBook junkie :-). HTML books should not be an issue (Safari), the real question is how the PDF will look like. According this video, reading PDF on iPhone should be fairly OK and iPod touch is same or better ...\nAnd according to this:\n\"Subjectively, the iPhone’s display is clearly superior to any computer display I’ve ever seen. While this is a function of many factors, the high pixel density plays a huge part in creating the extraordinarily tack-sharp perception\" Hmm, that sounds very good. Reading is all about display - the better screen, the more fun. Especially when you use properly formatted PDF - you can go for example to FeedBooks and use the PDF formatted for Sony PRS 500. It will certainly not offer Sony's battery life (it lasted for almost 2 weeks during my holiday) or readability in a bright sun ... but the screen and UI should make it up.\nLet's hope that the hack allowing install Skype (and other apps) and run it on iPod touch will come soon :-). If that happens, that's good enough reason for buying it - OS-X in a pocket ...\n","date":"September 10, 2007","externalUrl":null,"permalink":"/posts/2007-09-10-new-ipod-touch-as-ebook-reader/","section":"Posts","summary":"As the September 28th is approaching (the day when the new iPod touch will be available in Canada), I have a real dilemma: do I go with the \"iPhone without the phone\" or not ? The price $329 for 8 GB iPod is pretty high - compared to $279 for 80GB classic - which would allow me to carry all my music, some movies and all podcasts with me. On the other hand, the Touch has WiFi and can be used as pretty decent Web browser on top of iPod functionality.\n","title":"New iPod touch as ebook reader ?","type":"post"},{"content":"\"Data visualization: Modern approaches\" - great read, highly recommended. Available here.\n","date":"September 9, 2007","externalUrl":null,"permalink":"/posts/2007-09-09-great-article-on-data-visualization/","section":"Posts","summary":"\"Data visualization: Modern approaches\" - great read, highly recommended. Available here.\n","title":"Great article on data visualization","type":"post"},{"content":"Hi, all Java gurus inside and outside of Thinknostic - I have a very interesting problem. Imagine the following situation: we have three existing Java Web applications, written back in 2000/2001, based on open source libraries of that time: Struts 0.9/1.0 and JSP 1.x (no JSTL) with Tiles for Web layer, Apache Torque for ORM, early version of Quartz for job scheduling, Jasper Reports for PDF reports and Freemarker as template engine for email creation. The application has been (and still is) in production for almost 7 years and works great. Now the customer is expanding the functionality and wants add several Ajax features - in short, version 2.0 is on the table.\nAs part of adding new functionality, we will be updating the foundation libraries to make sure we are current with the latest and greatest mainstream libraries and frameworks and that the application will (after the enhancements) work for another 5-7 years without needing major updates. The criteria for updates of the base libraries are:\na) must be open source (preferred Apache or BSD license)\nb) must be mainstream technology (availability of skills and longevity of project)\nc) simple is better than complex\nOne pretty much given is \"metaframework\" which will be Spring. I have looked into some other IoC containers but did not find any compelling reason not to use Spring. The newest Google creation - Guice - looks pretty interesting (if you like annotations and hate XML) - it is much smaller and very lightweight - but as we will need many of the Spring modules anyway (besides configuration at least AOP, transaction support, events, persistence layer integration, scheduling etc), it is simpler use just Spring. Besides, Springs works great with POJO as business layer.\nFor data layer, I am considering replacing Torque (which evolved since 2000 and upgrading code to version 3.x would require non-trivial changes) either with most \"standard\" ORM mapper today - Hibernate, or (alternatively) going away from the full ORM (which is not really required) to just iBatis as thin layer on top SQL. Spring supports both Hibernate and iBatis very well. One argument for iBatis is that it makes much easier for DBA to understand and adapt SQL queries the application is using, compared to Hibernate magic and SQL generation.\nOn Web framework side, we will stay with latest version of JSP with JSTL and most likely use Spring MVC as UI framework. Struts 2.x is quite different from what we have used before - so staying with Struts would not be such an advantage as it may seem. The main argument for using Struts is amount of books, skilled people and availability of tools - but unfortunately, if you discount Struts 1.x and focus on Struts 2.x only, Spring is probably as good choice if not better from market share point of view (and is IMHO much more open and flexible). I was briefly contemplating using alternative view technologies (Freemarker instead of JSP) as I am not big fan of \"servlets in disguise\" - but both Freemarker as well as Velocity are much more niche technologies which may not be popular in 2-3 years from now.\nOne change that I am going to evaluate is using Sitemesh instead of Tiles - I did not worked with it yet, but the examples I tried look very promising (and Matt Raible uses it it AppFuse ;-)). Speaking of it, Matt also would not use Struts 2 :-)\nThe last open question is on Ajax side. My experience with Ajax framework was so far exclusively outside of Java world - either Rails (where it is amazingly simple) or in ASP.NET (where it may be easy or hard, depending on haw you do it). With Java (and Spring) there is - as usual - many options and I need to do some research and evaluation. I will get back to it. Let me know if you have any suggestions or recommendations - ideally from real life Spring MVC experience. Thanks in advance.\n","date":"September 6, 2007","externalUrl":null,"permalink":"/posts/2007-09-06-fresh-cup-of-java/","section":"Posts","summary":"Hi, all Java gurus inside and outside of Thinknostic - I have a very interesting problem. Imagine the following situation: we have three existing Java Web applications, written back in 2000/2001, based on open source libraries of that time: Struts 0.9/1.0 and JSP 1.x (no JSTL) with Tiles for Web layer, Apache Torque for ORM, early version of Quartz for job scheduling, Jasper Reports for PDF reports and Freemarker as template engine for email creation. The application has been (and still is) in production for almost 7 years and works great. Now the customer is expanding the functionality and wants add several Ajax features - in short, version 2.0 is on the table.\n","title":"Fresh cup of Java","type":"post"},{"content":" A linguistics professor was lecturing to his class one day. \"In\nEnglish,\" he said, \"A double negative forms a positive. In some\nlanguages, though, such as Russian, a double negative is still a\nnegative. However, there is no language wherein a double\npositive can form a negative.\" A voice from the back of the room piped up, \"Yeah, right.\"\nFound on the Net :-)\n","date":"September 3, 2007","externalUrl":null,"permalink":"/posts/2007-09-03-double-negative/","section":"Posts","summary":" A linguistics professor was lecturing to his class one day. \"In\nEnglish,\" he said, \"A double negative forms a positive. In some\nlanguages, though, such as Russian, a double negative is still a\nnegative. However, there is no language wherein a double\npositive can form a negative.\" A voice from the back of the room piped up, \"Yeah, right.\"\nFound on the Net :-)\n","title":"Double negative","type":"post"},{"content":"After three amazing weeks, I am back again on-line - reading through emails and trying to sort out and process over 15 GB images. Shooting RAW has consequences :-).\nSome of the see-worthy places and stories from the trip will start appearing here as the time permits to process my notes from the road. Stay tuned ...\n","date":"August 28, 2007","externalUrl":null,"permalink":"/posts/2007-08-28-back-again-2/","section":"Posts","summary":"After three amazing weeks, I am back again on-line - reading through emails and trying to sort out and process over 15 GB images. Shooting RAW has consequences :-).\nSome of the see-worthy places and stories from the trip will start appearing here as the time permits to process my notes from the road. Stay tuned ...\n","title":"Back again","type":"post"},{"content":" Europe 2007 - 1: Switzerland, Lower Engadin # The flight went pretty quickly. It was less than 7 hours, anyway. We crossed the night and the Atlantic in a short time and landed at 6 AM in rainy, wet Zurich.\nThe car I have retrieved from Europa car was Spanish Volkswagen make – Seat Leon. According the specification, it was a “medium size car”. And it maybe was, for European circumstances. For me it felt fairly small – our luggage did barely fit into the trunk. If we had more than two normal size and one half size cases, we would be in trouble. One small piece had to fit behind my seat.\nThe car was of course diesel and of course manual. The first feature was great – it had almost negligible consumption (somewhere around 4-5 liters per 100 km). You can more appreciate this fact considering the prices of gas ranging from 1.1 to 1.4 Euro per liter. The second was a bit stressful at the beginning: dealing with changing gears, fatigue from the flight without sleep, heavy rain and Swiss crowded highways was a bit challenge when we started.\nSwitzerland has excellent street system, very dense and comprehensive and pretty decent street signs (for Europe at least). Two minor annoyances were placements of the street lights – at the beginning of the junction – and street signs, which are high up on the buildings in the streets. I started to appreciate how easy is it in Canada / USA to find out where you are, as the street names are in the junctions as well. Knowledge of local Autobahn map also helps, without it you may face a challenge of “omnidirectional signs”: the Autobahn splits and left side goes to Zurich, Schaffhausen, Winterthur, Luzern, Chur, Lugano, Bern, Basel (which happens to cover every direction imaginable) and the right side goes to Zurich, Luzern, Chur, Lugano, Bern, Basel, Geneve. Now make your choice when you go to Luzern and Chur 🙂\nDespite these challenges, we made it in one piece to Thomas place with quick shopping stop at Oftringen. For security reasons, I took a short nap and around 5 we were on the road again towards Chur, Fluellapass and Scuol. This is the region of Lower Engadin, very similar (only less known and little harder to reach) than more famous destinations of Davos and Sankt Moritz.\nThe way to Scuol takes you through amazing picturesque central Switzerland roads, with many curves and tunnels, raising up to almost two thousand meters of mountain passes. We have cheated a bit and tried the Klosters‘ car rail. You drive onto a steel road, which happens to be on rails. After that, you sit in the car and wait until the locomotive takes you through to the other side of the mountain – in about 20 minutes. There is not much to see, except darkness and the car before you in your car’s lights.\nWe had a bit scare during the ride – as the train accelerated, the laws of physics and not properly activated handbrake on the car before us caused that it started to move toward us. Fortunately, it was only short distance, slow speed so it softly landed, touched our bumper without any visible damage … but it was pretty scary sight, as the car before us was a full size (American full size) van, for 7 people, with Belgian plates and full of kids. So we had more excitement on the simple tunnel ride than on a Halloween’s spooky ride on Saunders farm, and for even less money – 27 francs one way 🙂\nAt about 8:30 PM we arrived to Scuol. Thomas booked pretty good hotel – as we discovered later, most likely the best hotel in Scuol. During the season, it is not easy to book hotel for less than a week – so if your stay is 3 days, you most likely end up with fairly expensive ones.\nThe cuisine in the Hotel Belvedere was excellent. I enjoyed most the breakfast, with home made special kind of Bircher Muesli and excellent selection of Swiss cheeses of all kinds and ripeness. The dinner was true work of art and culinary sophistication – probably above my capabilities of full appreciation, but very yummy and pleasantly surprising.\nHiking in Parc Naziunal Swizzera # The weatherforecast for the Wednesday was fairly bleak – rain, mist, cloudy and little (if any) sun. We took off for the trip after an great breakfast (I switched to Igor’s famous “python mode” – big breakfast and big dinner, nothing in between except some fruits and looots of water). What looked like a small walk ended up to be about 9 hour hike with highest point well over 2000 meters and almost 1000 meters absolute height difference. The lesson learned is that it is not advisable to try keeping up with fanatical mountain-biker who is in a great shape (ready for 180 km bike marathon in the mountains). I have walked few hundreds of kilometers this year around Ottawa, but the mountainous terrain is completely different ball game. Thomas’ pace of going uphill was simply too much. He started about 20% faster than my comfort zone speed – and kept on increasing speed … After few hours I found that my lungs are definitely too small for my body size, and as result me and Silvana took a shortcut back. My wife with Thomas and his wife finished the full hike – well over 9 hours.\nWe have experienced about 10 different weather types during the day – everything from sunny and pleasantly, through cold wind up to heavy rain, changing on 10-15 minutes intervals. I have taken a lot of pictures, selection of which can be seen here.\nThursday – Around Scuol # For Thursday, Thomas planned to take even longer and more challenging hike (up to 3000 meters) – so we decided to explore the arounds of Scuol on our own. The weather forecast was computationally complete – the weathermen have promised all the weather you can imagine – and (unfortunately) did deliver. As Thomas told us at the dinner, they even have had the snowstorm and ice pellets in close to 3000 m heights. We missed these, but otherwise we have seen rain, fog, blazing sun with perfect cloud-free sky, cloudy – all of that at least 3 times.\nAfter short walk in the very Swiss “downvillage” of Scuol we took the cable car up to Motta Naluns (the accomodation included the free ride on cable car, buses and trains in the Lower Engadin). The view was amazing – see for yourself. There is something special in the Alp meadows, something that not even much bigger mountains do not have. I have been in Canadian Rockies, but – however they are beautiful, I have never seen anything like this there.\nSo while Thomas was walking up the 3000 meters pass, we were enjoying the panorama-trail on he to of and we have experienced the paragliders start and disappear in the fog – which arrived within 10 minutes from nowhere.\nPretty close to Scuol is Bad Tarasp – small village with castle and termal springs. If you drive there, the road is something special – very narrow, serpentines carved into very steep hill, just barely wide enough for single car. Bidirectional, of course – the curves have wider spots – only spot where two car can pass. We were driving it in a bus, which made the experience even more scary. Actually not a bus but “Postauto” – which looks (and also is) an ordinary bus, painted in colors of and operated by Swiss post. Nice optimization – in addition to speedy post delivery it takes care of the people transport as well.\nThe castle in Tarasp has very interesting history – rebuilt from a complete ruin during 1900-1915 by very wealthy German enterpreneur Karl Lingner, who made fortune on cosmetic industry, visited the Tarasp, fell in love with the place, purchased the ruin and (after sinking few millions of francs into reconstruction) brought it to it’s todays appearance. The castle contains lots of truly amazing historical pieces of furniture, some of the few centuries old, purchased from monasteries and castles all over Europe. During the years 1910-1914, with World War I looming over Europe, many people and organizations were more than willing to convert their belonging into much more portable assets than 16th century wooden bed with baldachin … Thanks to Swiss neutrality, these marvels of art survived intact here.\nUnfortunately, taking pictures was not allowed inside the castle, so you can see only few shots of the castle from outside and the village Tarasp here.\nHotel Belvedere is about 200 m away from thermal bath with mineral, healing water and is actually connected to the bath by wooden walkway, which takes you over the streets of Scuol directly to the bath. There are several pools with different kind of water and the water really works wonders – as my wife can confirm. The setup is very convenient, you can put on swimming robes in your hotel room, take the elevator down to minus second floor (do not forget that the first floor is Floor 0, not one) and walk right up to the pool. This is one of main attractions of the hotel and you can tell that by amount of people in retirement age visiting (most of them were elderly ladies speaking Italian). The bath is not exactly cheap – entrance fee is about 20 francs (18 CAD) per head and visit – but it was also included as part of the accommodation deal. If you travel with kids, be warned that children under 16 are allowed to enter only after 11:00 AM – for no obvious reason. Well – rules are rules, and “Ordnung muss sein ” \u0026hellip;\nObviously, I have not taken any pictures in the baths :-). As a curiosity, part of the service offering is the Roman bath – offering the real experience of the bath in Roman empire – naked, without any swimming suits. Despite that the entrance into Roman bath was also part of the package, we skipped this one \u0026hellip;\n","date":"August 20, 2007","externalUrl":null,"permalink":"/posts/2007-08-20-europe-2007-1/","section":"Posts","summary":"Europe 2007 - 1: Switzerland, Lower Engadin # The flight went pretty quickly. It was less than 7 hours, anyway. We crossed the night and the Atlantic in a short time and landed at 6 AM in rainy, wet Zurich.\nThe car I have retrieved from Europa car was Spanish Volkswagen make – Seat Leon. According the specification, it was a “medium size car”. And it maybe was, for European circumstances. For me it felt fairly small – our luggage did barely fit into the trunk. If we had more than two normal size and one half size cases, we would be in trouble. One small piece had to fit behind my seat.\n","title":"Europe 2007 - 1","type":"post"},{"content":" Europe 2007 - 2: Südtirol and Verona # Welcome to Italy: Verona # After the breakfast, we took off from Scuol direction Martina, via brief drive through Austria to Italy. If I would not consult the map, I would barely noticed the border crossing, because there was no passport control on neither of the Switzerland-Austria or Austria-Italy border. You will not really notice that you have left Switzerland either, unless you notice the prices on gas stations being suddenly in Euro. And you will definitely not notice you are in Italy for quite a some time as the villages will still look very German (or Austrian, if you wish), with signs in German (and often in gothic Schwabach letters). This region – south Tirol aka Sud-Tirol aka Trentino – Alto Adige – is ethnically and historically part of Austrian empire and is part of Italy for less than 100 years.\nThe drive through the Sud-Tirol is worth every gallon of gas. You go down for hours, meandering through the valleys with apple orchards everywhere. Never in my life I have seen so many apple trees. My wife was tried to take a picture of some them. Judging by amount of of images on the card, she must have missed at least half of them :-).\nAfter few kilometers, the endless apple orchards start and continue until (almost) Lago di Garda and Verona, later on intermixed with grapes, peaches and plum trees.\nAt the gas station where we stopped for lunch break, I had my first of many coffees – the Italian way. The minuscule cup contains about 30 drops of oily liquid – coffee – that contains about as much caffein as three extra large Tim Hortons mugs. And costs about the same as three Tim Hortons … Here we also saw parking the Italian way.\nWe had no reservation for this night, and planned to stay in Verona, so our first concern was to find a hotel. For all other nights we had reservations and new exactly where to go. It was easier than expected: on the way from highway exit to Verona Nord, following the Google directions towards Verona Centro, we first saw the signs of the Hotel Elefante and after about 4 km the hotel itself. At the first sight, it was not very appealing, but we decided to stop and try it out. I am happy we did. The hotel’s inside was very nice and charming – located on fairly large lot, with huge garden, it has in addition to main 2 story building about 5 or 10 small bungalows around the lot. Very cosy and welcoming, with excellent breakfast buffet and peacocks in the garden.\nWe unloaded the luggage, got the map and directions from the receptionist (who btw spoke very good English) and drove to Verona. We parked where she recommended and walked to historical downtown. How wonderful beginning of the Italy trip. Verona is small, friendly, clean. At the centre of the city is very nice piaza with over 2000 year old Arena – an amphitheater from the Roman Empire, used to host opera performances in the summer. The repertoire is obviously Italian opera (so if you are a Wagner buff, too bad – sorry Ivan L., you will not like the programming). On the night of our visit they performed Verdi’s Nabucco.\nTickets to arena performances are very expensive – they range (for better seats) from 100 to 300 Euro. You can buy them in front of arena, and there were several people selling them. We were extremely lucky to find a gentlemen with very British accent trying to get rid of single ticket for the staircase for just 25 Euro. Should he have more, we would all be seeing Nabucco – this way, only the most devoted opera fan from our family – my wife – went to see it, while me and Silvana went for a walk through the evening Verona. We saw the Juliet’s balcony, many beautiful streets, visited few bookstores, went for some gelato and coffee and returned back to nicely illuminated arena.\nFrom what I heard from Darina, the opera was an amazing experience. The seat she had did not have the best acoustics – which was to be expected with that price tag. She did not mind, as she saw Nabucco well over 50 times and knows the music and text by heart – but the atmosphere of the place was very powerful. Unless you really cannot stand opera, this is something worth trying during summer in Verona. The less expensive tickets needs to be booked well ahead (several months) as they go very quickly.\nWe have returned around midnight, tired but very happy about the lucky coincidence. So far – Verona is nicest Italian city we have seen (including all previous trips)\nWhat a start.\n","date":"August 20, 2007","externalUrl":null,"permalink":"/posts/2007-08-20-europe-2007-2/","section":"Posts","summary":"Europe 2007 - 2: Südtirol and Verona # Welcome to Italy: Verona # After the breakfast, we took off from Scuol direction Martina, via brief drive through Austria to Italy. If I would not consult the map, I would barely noticed the border crossing, because there was no passport control on neither of the Switzerland-Austria or Austria-Italy border. You will not really notice that you have left Switzerland either, unless you notice the prices on gas stations being suddenly in Euro. And you will definitely not notice you are in Italy for quite a some time as the villages will still look very German (or Austrian, if you wish), with signs in German (and often in gothic Schwabach letters). This region – south Tirol aka Sud-Tirol aka Trentino – Alto Adige – is ethnically and historically part of Austrian empire and is part of Italy for less than 100 years.\n","title":"Europe 2007 - 2","type":"post"},{"content":" Europe 2007 - 3: Pisa, Tirrenia and Firenze # Pisa and Firenze # After wonderful evening in Verona, the next day after a very good breakfast (they even had whole-wheat breads), we spend few hours in the garden of the hotel and taking pictures of the peacocks and around 10:30 we left towards the coast, south and the leaning tower.\nThe road we took was mostly on toll highways – the directions in Google maps were very useful. Not far away from Pisa you start to see the oleanders in the space dividing the highway directions – something that in my mind was always intimately related to being in Italy.\nThe hotel we had reserved was located not very far from the railroad station. We got there easily, the only excitement was (after unloading the luggage) getting to the parking spot. Hotel has the garage about 150 m away from it, and the shortest way there would require going twice in the opposite direction in a one-way street. I asked the guy at the reception for directions how to get there. He was very enthusiastic to help and went out to navigate me – using the shortest path :-). No polizia, no problemo. Viva la Italia.\nThe main attraction in city of Pisa is Piazza Dei Miracoli – the only part of Pisa the most people know about. We have been there before, but it always makes the same very deep impression of very special place. We went there first in the evening of the arrival, walking (about 25 minutes) from the hotel. There were many more people than when we were visiting back in September 1993. At that time, we just made a quick stop on the drive from Calabria to Switzerland and had only 1-2 hours. This time, we did have time and really enjoyed all four of the monuments: Duomo, Battistero, the Tower and the Camposanto. We did not go up on the tower – the lineup was too long for my taste – but spent lot of time in Duomo and the Camposanto. You need tickets for all of these, sold in the museum at the end of the street, prices are very reasonable. The best deal is to buy basilica entrance separately and then the “two pack” allowing to enter the other two. But there are many other nice places besides the Piazza in Pisa – as you can see here …\nIn Pisa we have started our culinary excursions into la cucina italiana vera – true Italian cuisine. Around the Piazza, there are lots of restaurant, with the “headhunters” on the street trying to convince you in. Almost every one had sitting on the street as well as indoor. Our criteria was stop and while reading the menu (also conveniently located outside) listen how many italian speaking people were there: we never went to restaurant that was either too empty or occupied mostly by mostly foreigners (meaning non-italian speaking guests). It worked like charm. We had the most tasty pastas and antipastas I have ever eaten. The best were simples dishes – Spaghetti carbonara or Pasta Frutti di Mare. I do not know how they do it, but it just taste so much better …\nWe have stayed two days in Pisa, because of the sea proximity, we went for a splash on day two. The drive to sea is about 20 minutes and there are beaches all around. The receptionist recommended us Tirrenia rather that Lido di Pisa, and we ended up there. Originally we wanted to drive down to Cecina, but decided to stop at Tirranea and give local spiaggia a try. It was great so we stayed. If you arrive early, there is lot of good parking on the street. Not free, but very affordable, 1 Euro for 2 hours. Considerably cheaper than in Ottawa downtown :-).\nThere is not much to add to being at the see – water was warm, waves just right, beach much cleaner that I have expected. At this point I started to re-evaluate the myth that “you have to drive down to south because sea and the beaches in the north are dirty”. That may be true in the east coast around Bibione and Venezia, but certainly not in here. Some pictures are here.\nSilvana loved the sea so much that we planned to stay another day at the Tirranea and drive to Sienna afterwards. The heavy rains in the morning and weatherman promising rains at the coast but better weather more inland, made us switched to Plan B – brief tour of Florence instead.\nPisa and Florence are interconnected by very good, toll-free highway named PI-FI-SI, standing for Pisa, Firenze and Sienna. It is also fairly close – about an hour drive and not very interesting. The real fun begins afterwards, when you actually arrive to Florence and try to navigate there. The web of one-way streets with heavy construction sites, badly marked detours and Italian driving habits makes it life-long experience.\nAfter about 40 minutes and about 15 wrong turns we (by pure accident) ended up in parking garage close to railway station and not very far from where we actually wanted to be. The entry to parking was about 45 degrees steep slope downwards, barely wide enough for two small cars, with a right angle turn in the middle. It is also the only entrance and exit for both the cars and the customers of the garage … so you really have to awake that sleeping Italian deep inside you and take it easy when a pedestrian jumps into front of your car. I have seen a car going downwards to stop in front of the curve, unload baby carriage (fortunately empty) to get out something from the trunk, place it in the other lane right behind the curve ….\nThe cars are parked in two levels in one-car lifts. you have to give them the car keys. Leaving fully loaded car with all our luggage created a bit uneasy feeling in me at first – but nothing disappeared, all was OK.\nFlorence as city was a big disappointment, mostly because of the mismatch between the hype and reality (we have had very high expectations) – but also because we have been comparing to Verona and Pisa. It was overcrowded, with literally thousands of people everywhere, huge lineups to any attractions. Lesson learned – never visit in high season – June or September may be much better. For me, all atmosphere was killed by the commerce – very aggressive attempts to make most money from swarms of tourists: the kiosks selling everything are everywhere. In addition to selling articles actually connected to the city (souvenirs, T-shirts, leather products) you see lot of fake brand merchandise – sunglasses, Rolex watches, bags, clothing – you name it. As if these kiosks would not be enough, there are large amounts of “mobile” sellers – walking around with their collection and annoying people around.\nI was really surprised why the selling of the fakes is tolerated by the police. Legally, in Italy not only selling but also knowingly buying these counterfeits is a crime…\nThe city itself is not very well preserved and maintained as the hype would make you believe. Having no time to go into museums (waiting in line to get there would take hour or more) we walked around parts of historical core, visited Ponte Vecchio – which looks very nice from the distance. Unfortunately, the bridge itself is loaded with jewelry and touristware junk selling stores. I would much more appreciate to have an opportunity to see (and buy) some traditional hand crafted products of local craftsmen – rather than jewelry and toys Made in China.\nWe did not stay too long and are leaving around 4 PM to get to Siena while there is still daylight. The evening comes every time sooner – not only as August progresses, but as we go south, we are really moving eastward as well, which means earlier sunrises but also earlier sunsets.\n","date":"August 20, 2007","externalUrl":null,"permalink":"/posts/2007-08-20-europe-2007-3/","section":"Posts","summary":"Europe 2007 - 3: Pisa, Tirrenia and Firenze # Pisa and Firenze # After wonderful evening in Verona, the next day after a very good breakfast (they even had whole-wheat breads), we spend few hours in the garden of the hotel and taking pictures of the peacocks and around 10:30 we left towards the coast, south and the leaning tower.\n","title":"Europe 2007 - 3","type":"post"},{"content":"","date":"August 20, 2007","externalUrl":null,"permalink":"/tags/italy/","section":"Tags","summary":"","title":"Italy","type":"tags"},{"content":"","date":"August 20, 2007","externalUrl":null,"permalink":"/tags/switzerland/","section":"Tags","summary":"","title":"Switzerland","type":"tags"},{"content":"In case you were wondering why the blog went silent - I am touring Europe (Switzerland and Italy). Will post some stories after return ... and pictures on Smugmug - promise !\nGreetings from Rome (just made it here tonight)\n","date":"August 15, 2007","externalUrl":null,"permalink":"/posts/2007-08-15-on-vacations/","section":"Posts","summary":"In case you were wondering why the blog went silent - I am touring Europe (Switzerland and Italy). Will post some stories after return ... and pictures on Smugmug - promise !\nGreetings from Rome (just made it here tonight)\n","title":"On vacation","type":"post"},{"content":"With the latest software update (I am now on 1.0.3), one of the issues to be fixed was the \"charging indicator behaviour\". Looks like it was indeed the software bug. After upgrade, the indicator jumped to full 4 bars and stayed there. Beforehand, I had usually only 3 bars regardless how long it was charged.\nTime will tell - I am taking the reader with me to Italy to get some mileage out of it, during transatlantic flight ...\n","date":"August 6, 2007","externalUrl":null,"permalink":"/posts/2007-08-06-sony-ereader-charging-problem-fixed/","section":"Posts","summary":"With the latest software update (I am now on 1.0.3), one of the issues to be fixed was the \"charging indicator behaviour\". Looks like it was indeed the software bug. After upgrade, the indicator jumped to full 4 bars and stayed there. Beforehand, I had usually only 3 bars regardless how long it was charged.\nTime will tell - I am taking the reader with me to Italy to get some mileage out of it, during transatlantic flight ...\n","title":"Sony eReader - charging problem fixed ?","type":"post"},{"content":"For all my fantasy-loving friends who consider reading in Czech or Polish too inconvenient: the first book of the grand master Andrzej Sapkowski in English is out. It is book of short stories about Geralt, the Hexer (or Witcher if you want), who is the main character of the 5-book saga with the same name.\nYou can get it on Amazon.\n","date":"July 30, 2007","externalUrl":null,"permalink":"/posts/2007-07-30-sapkowski-in-english-is-out/","section":"Posts","summary":"For all my fantasy-loving friends who consider reading in Czech or Polish too inconvenient: the first book of the grand master Andrzej Sapkowski in English is out. It is book of short stories about Geralt, the Hexer (or Witcher if you want), who is the main character of the 5-book saga with the same name.\nYou can get it on Amazon.\n","title":"Sapkowski in English is out !","type":"post"},{"content":"Yes, such nice tool really exists and it's name is Remember the Milk.\nAt first sight, RTM is not extremely visually appealing, but very nice and very usable Ajax application. After some time using it, you may better appreciate the \"less is more\" design. The offline access is thanks to Google Gears magic. Just flip the small green arrow (which will download your data to local cache) and voila - you can go offline, keep editing or adding tasks - your changes will be remembered. Later on, after going online the changes will be synced back.\nThe RTM has another killer feature - it integrates very well with Google calendar. Your tasks with due dates (which all meaningful task should have) will appear in you calendar without needing to go to RTM site. You can even edit them from there. For details, see the help.\nRTM has pretty much everything what most people may need: projects, lists, tagging, locations (with map integration), contacts - with task delegation, and of course, API. Give it a look ...\n","date":"July 29, 2007","externalUrl":null,"permalink":"/posts/2007-07-29-web-based-task-manager-with-offline-mode-finally/","section":"Posts","summary":"Yes, such nice tool really exists and it's name is Remember the Milk.\nAt first sight, RTM is not extremely visually appealing, but very nice and very usable Ajax application. After some time using it, you may better appreciate the \"less is more\" design. The offline access is thanks to Google Gears magic. Just flip the small green arrow (which will download your data to local cache) and voila - you can go offline, keep editing or adding tasks - your changes will be remembered. Later on, after going online the changes will be synced back.\n","title":"Web based task manager with offline mode - finally !","type":"post"},{"content":"I have been pretty quiet during last month. Few reasons why, none of them business related. The summer is not the season where people in our industry are incredibly busy - that's what winter is for ... and end of March, government fiscal year end ;-). We had family visit - my two nephews were staying with us for few weeks. So instead of blogging, I was spending evenings with them and weekends as a tour guide around Ottawa's attractions. I have even - finally, after 9 years in this country - overcome my dislike for really long car trips and visited Niagara Falls.\nThe waterfall and nature was amazing. The stuff built around it by tourist industry was not. Even the drive would not be so bad (only too long) - unfortunately somebody did place Toronto between Kingston and Niagara :-( ... with all the consequences like never ending traffic jams and way above average number of crazy drivers. The crazy means crazy even compared to Montreal.\nAfter the nephews departure at the end of the last week, the most important event of the year 2007 happened: the Book 7 alias Harry Potter and the Deathly Hallows arrived. We finally know where was Snape's true loyalty and whether Harry made it or JKR ignored plea from Stephen King and other writers and killed him. On July 20th in the evening, I was there, in my home Chapters with my wife and daughter and hundreds of others, waiting for the midnight. It was amazing. Not the marketing hype, but the anticipation and the atmosphere (my compliments to the guy dressed as Lucius Malfoy, he was bang on).\nThere is something strangely satisfying to see people stand in line to buy a book. Other that HP series, I have never seen it happen on this continent. Regardless whether you like the story or not, what JKR achieved (in addition to make some pretty nice wad of cash for herself and others) is bringing people back to books and to reading. Not only kids. Reading books is essential - just watch Idiocracy to see where the TV will lead you ;-)\nSo hour after midnight I was home with the Book 7 and started to read. I have finished shortly before midnight same day - with short break for sleep. What a weekend ! The book seven did certainly not disappoint. I will not go to details - not even now when Connie finished it and hopefully Shane did as well, some of my friends may still be reading. Gabo - wikipedia has full plot outlined, so unless you want to get a spoiler, do not go here ...\nIn some sense, the Harry Pottter saga was like a greatly written piece of software. JKR created illusionary world which was very rich and very consistent. Even with allowing magic, there were rules and things worked within the system. In software, you must pay attention to details (otherwise it will not work) and whenever you are writing larger system, your design should be solid otherwise your own creations may get in your way. In the books 1 to 7, I have not found any major contradictions or ugly hacks. Well thought-over plot, nicely designed story development, perfectly implemented - I mean written. Hats off. You can seldom see this gift in fantasy stories - somehow dealing with magic and dragons often lures the writers to be sloppy, cut corners, ignore details and bend the rules. There are few exceptions - such as Belgariad, Discworld or The Hexer Saga (to read this one you better can read Polish or Czech). From \"scientific\" sci-fi, one of the best \"software-like artworks\" is IMHO Dragon's Egg and Starquake.\nThanks for all the magic, JKR.\n","date":"July 27, 2007","externalUrl":null,"permalink":"/posts/2007-07-27-most-important-event-of-the-year/","section":"Posts","summary":"I have been pretty quiet during last month. Few reasons why, none of them business related. The summer is not the season where people in our industry are incredibly busy - that's what winter is for ... and end of March, government fiscal year end ;-). We had family visit - my two nephews were staying with us for few weeks. So instead of blogging, I was spending evenings with them and weekends as a tour guide around Ottawa's attractions. I have even - finally, after 9 years in this country - overcome my dislike for really long car trips and visited Niagara Falls.\n","title":"Most important event of the year","type":"post"},{"content":"Once upon a time, there was an application named Democracy Player. A really neat one, capable of downloading videos from internet and playing them in multiple formats. It even can download YouTube videos.\nFor some reason, the Democracy Player name was replaced with a new name. My name. The Democracy Player will be know as Miro. I have not discovered why this name was chosen, or if it means something. Maybe the guys responsible for it had similar thoughts as my parents over 40 years ago :-).\nIt is kind of strange feeling to share the name with piece of software. I am not alone - for example one very famous golfer shares the first name with an operating system. A very likely greatest golfer sharing name with very likely greatest operating system :-). But as we know, after Tiger comes Leopard - so the match will soon be over, unless Mr. Woods would consider a name change :-). I guess Leopard Woods does not sound anywhere as good as Tiger, but certainly better than Vista Woods ....\nIn all this, I am very thankful that the application I share my name with is a good and decent one. Free. Open Source. Runs on Windows and Linux and Mac. Can even play HD content (free one). I guess I could end up much worse ...\nSo if you are interested in free, opensource, multi-platform video player, go and get Miro. The other one :-). I will do the same and I will maybe even join Miro mailing list and become Miro member :-).\n","date":"July 18, 2007","externalUrl":null,"permalink":"/posts/2007-07-18-end-of-democracy-or-how-i-turned-into-platform/","section":"Posts","summary":"Once upon a time, there was an application named Democracy Player. A really neat one, capable of downloading videos from internet and playing them in multiple formats. It even can download YouTube videos.\nFor some reason, the Democracy Player name was replaced with a new name. My name. The Democracy Player will be know as Miro. I have not discovered why this name was chosen, or if it means something. Maybe the guys responsible for it had similar thoughts as my parents over 40 years ago :-).\n","title":"End of democracy - or how I turned into platform","type":"post"},{"content":"It's been over 10 months since we have started to seriously use virtualization and run Windows inside virtual machine to ease installation and configuration pain. It starting first as convenient measure of isolation two different development environments (.NET 1.1 based and .NET 2.0 based) and avoid \"crosspolination\" in the data analytics project. At that time, my expectations what would be the limits of what you can or cannot do in virtual environment were mostly around performance, responsiveness and device support (USB especially). As it turned out, all of that actually worked much better than I have ever expected. With new versions of Parallels, the performance is very good and user experience (user means fellow developer) is barely noticeable difference against developing on host system. Assumed that you have decent dual-core system with 2 GB of RAM, of course. Using Parallels gives you the added benefit of moving the virtual environment between Windows, Mac and Linux hosts, which is very convenient.\nWe have also started to use virtualization on the server side, using Microsoft Virtual Server 2005 R2 and I am happy to report that it worked very smooth as well. In the biometric project, we were running UA testing on circuit of 5 instances of replicated SQL Servers, each server using own virtual machine. The circuit was hosted on two quad core (2x dual core) servers with 4GB RAM each. Using virtual machines allowed us to achieve repeatability and consistency in configuration setting up the environment - we cloned one install and renamed the VM's hosts.\nAnd here comes the catch: because it is very easy to copy virtual disk in order to test some new software or plugin or configuration, after some time we have ended up with quite a collection of virtual machines and experienced first limit of virtualization: configuration management. It is pretty hard to keep exact track of what is exactly installed in which VM - what version of which software, what are the network settings, user accounts, access rights. It can easily lead to administrative nightmare and can require effort comparable with managing environment of hundreds of computers (it essentially is that environment). In development shop as ours you can cheat a bit a standardize on same usernames and passwords for each VM, but it is not very secure and hardly recommended approach for production ...\nSecond limit we have seen is Windows update effect. The VM's which represents \"alternative universes\" seldom run at the same time. With Windows updates coming almost daily, first things that happens after you get back to start using VM which was sitting idle for 3 months is installation of 37 updates, interwoven with 7 reboots. A pretty time consuming and boring activity. If you are math-geek, you can define a function that will compute number of wasted hours from number of VM's, their inactivity and frequency of security updates - and find out how many VMs you should own so that all your working hours would be consumed by switching the VM's on / off and waiting for the updates to finish ...\nThere is no really 100% good solution for this. Running all VM's all time is not practical and switching the updates off completely is dangerous. Again, in development shop you can (and should) batch the updates an update in \"waves\" - it will still consume time, but at least the \"patchlevel\" of the VM's will be consistent and you will save some time with merging some reboots. And it is not only Windows updates that is causing problems: keeping e.g. versions of assemblies installed in GAC (or Ruby GEM's) in sync across multiple virtual machines can be a challenge too.\nThird challenge is licensing and license management. I do not mean the legal side of software licensing related to running software in VM's - just pure technical implications of doing it. Many software products and subscription based services are using client requests' tracking to enforce only allowed number of client installs. For example anti-virus, which must download almost daily new library version, can use the \"get update\" and current client version as mean to track that only licensed number of clients are getting the updates with same license id. It can get quite confused when you repeatedly roll back the VM state and return to starting point two weeks ago - or alternate running two different snapshots of same VM in time. Even if there is never more than single instance of VM running at the same time with the licensed version of software - and only one licensed copy was ever installed, it is very hard to distinguish this from situation where second (illegal) copy of software were installed on second host - virtual or not. I can imagine this will lead to some quite interesting challenges on both technology and legal sides ...\n","date":"July 16, 2007","externalUrl":null,"permalink":"/posts/2007-07-16-limits-of-virtualization/","section":"Posts","summary":"It's been over 10 months since we have started to seriously use virtualization and run Windows inside virtual machine to ease installation and configuration pain. It starting first as convenient measure of isolation two different development environments (.NET 1.1 based and .NET 2.0 based) and avoid \"crosspolination\" in the data analytics project. At that time, my expectations what would be the limits of what you can or cannot do in virtual environment were mostly around performance, responsiveness and device support (USB especially). As it turned out, all of that actually worked much better than I have ever expected. With new versions of Parallels, the performance is very good and user experience (user means fellow developer) is barely noticeable difference against developing on host system. Assumed that you have decent dual-core system with 2 GB of RAM, of course. Using Parallels gives you the added benefit of moving the virtual environment between Windows, Mac and Linux hosts, which is very convenient.\n","title":"Limits of virtualization","type":"post"},{"content":"","date":"July 10, 2007","externalUrl":null,"permalink":"/tags/photo/","section":"Tags","summary":"","title":"Photo","type":"tags"},{"content":"In the previous article I have mentioned the potential issue with some uploaded images hanging in state \"Processing image\" for surprisingly long time after upload and expressed hope that there is some background \"catch it all\" process that would take care of all these. As it turned out, there is. All uploaded images that were haging in the processing stage turned up to be fixed by next day or so (it was about 10-20 images out of about 3-4 thousand).\nHere is a simple trick how to make sure it is indeed so. After uploading a gallery, tag every image in processing with some distinctive tag, e.g. \"checkme\". Regardless in how many galleries, categories or subcategories your images will be, you will show them all by clicking on the checkme tag in your home page. After verifying that the images are OK, you can use bulk edit to remove the tag from all.\n","date":"July 10, 2007","externalUrl":null,"permalink":"/posts/2007-07-10-smugmug-processing-image-follow-up/","section":"Posts","summary":"In the previous article I have mentioned the potential issue with some uploaded images hanging in state \"Processing image\" for surprisingly long time after upload and expressed hope that there is some background \"catch it all\" process that would take care of all these. As it turned out, there is. All uploaded images that were haging in the processing stage turned up to be fixed by next day or so (it was about 10-20 images out of about 3-4 thousand).\n","title":"Smugmug \"processing image\" - follow up","type":"post"},{"content":"Week ago, my SmugMug 14 day trial period expired and (as expected) I signed up for the 1 year service. Here are my first impressions after over week of use, with over 3000 uploaded photos and 6.8 GB disc space consumed :-).\nGood news is - it really works as advertised and I still like it a lot. I have not really tried many of the features, but what I did try, worked as expected. The uploader (I am using the default, Java applet based drag-and-drop universal uploader) is very friendly - the small status windows shows not only status of the upload, but also the thumbnail of the uploaded image.\nEvery photo lives in the gallery and the galleries can be assigned into categories with optional subcategories. The system is pretty smart - when you create a gallery inside category (or category / subcategory), these are pre-set as defaults (which you can change, of course). The uploaded file names are parsed and \"meaningful\" words are automatically assigned as keywords. As long as the words are separated by spaces or underscore. This works best in English - some of my pictures have names in Slovak and the word stemming generated multiple keywords - but that is the price for not using English :-).\nProper tagging of images is a lot of work. Once you do that, though, the search using keywords is pretty effective. You have the classical tag cloud and can select the images by the keyword. SmugMug offers also related keywords and allows to further limit the search.\nI have decided to organize the photos chronologically, using categories and subcategories to denote year and months (one or more). This in theory can be achieved using built in time line, but more than 30% of my images are scans and have no EXIF data in JPG. It would be great if somehow there was a possibility to assign date (at least year or year and month) for the set of images - same way as keywords are assigned. However, this is not yet possible.\nWithin the categories / subcategories, you can have only one level of galleries. At first I thought that this 2 or 3 level fixed hierarchy will be too limiting and inflexible, but in reality, it is not such a big deal. In the occasions where I have nested folders with images - e.g. vacations folder named Europe and subfolders for Italy and Switzerland (where Europe contains all other images) - I simply created galleries named 'Europe', 'Europe / Italy' and 'Europe / Switzerland'. The slash indicated the folder structure on the server and sticking with the naming convention will allow to use the API and do automatic synchronization (using Ruby ;-))\nGetting images up there is quite time consuming. But after you have them uploaded, the fun begins. The viewing and navigation is where SmugMug really shines. I have seen many Web2-ish sites, but the paging here is one of the bests (if not the best). You can use either \"classic\" pager links:\nor dynamic (Javascript):\nLoading of the thumbnails and images is very fast and with reasonably fast Internet connection, you can get very good user experience. Even the slideshow - about which I did not have very high expectations - works surprisingly well. Much better that you would expect from a browser based solution. Because the images are intelligently scaled down on server side, doing slideshow in full screen with 3-4 seconds delay is not much different than using default Windows viewer with local LAN (where the images are transferred in full size and scaled to fit the window on client side) - especially when you have 3-4 MB images..\nThe only minor annoyance is long lasting \"Processing image\" syndrom. After you upload image, the back-end processes the image and during this time (in 99.9% of images few seconds) the image thumbnail and real image is represented by \"Processing image\" placeholder.\nand\nAs it happened in 2 or three cases during the upload of 3000+ images, the back-end processing never ended and even after few hours that particular image was still hanging in the state of processing. It is possible that this syndrome can be caused by the user (myself) opening the gallery being uploaded in second tab of the browser ... I am not sure whether there is some background nightly batch that will catch it - but it is a good idea visually verify the upload after it finishes.\nBtw, if you consider going with SmugMug, here is coupon code that will be give you $5 discount from the $39.95 yearly price: ndkpdNg15cgYI\n","date":"July 7, 2007","externalUrl":null,"permalink":"/posts/2007-07-07-first-week-with-smugmug/","section":"Posts","summary":"Week ago, my SmugMug 14 day trial period expired and (as expected) I signed up for the 1 year service. Here are my first impressions after over week of use, with over 3000 uploaded photos and 6.8 GB disc space consumed :-).\nGood news is - it really works as advertised and I still like it a lot. I have not really tried many of the features, but what I did try, worked as expected. The uploader (I am using the default, Java applet based drag-and-drop universal uploader) is very friendly - the small status windows shows not only status of the upload, but also the thumbnail of the uploaded image.\n","title":"First week with SmugMug","type":"post"},{"content":"go and get it - at http://www.ghisler.com/\nIt got nice visual upgrades - look and feel and icons are gently nicer and more XP-ish. Plus many other new features. Upgrade is still free for registered users.\nIf I should pick one single most useful program I ever used on any computer system, Total Commander would be clear winner. I do not remember when exactly I purchased the license - I guess sometimes around 1994-95, when it was named Windows Commander. Since that time, I was using it pretty much every day (except few short periods I was working exclusively on Unix). I still use it every working day (as I often spend weekends on Mac platforms).\nThanks, Mr. Ghisler. As you say in Switzerland - merci vielmals. The 40 Swiss franks spent on the Commander license back then was absolutely the best software purchase of last decade :-).\n","date":"July 5, 2007","externalUrl":null,"permalink":"/posts/2007-07-05-total-comander-version-701-final-is-out/","section":"Posts","summary":"go and get it - at http://www.ghisler.com/\nIt got nice visual upgrades - look and feel and icons are gently nicer and more XP-ish. Plus many other new features. Upgrade is still free for registered users.\nIf I should pick one single most useful program I ever used on any computer system, Total Commander would be clear winner. I do not remember when exactly I purchased the license - I guess sometimes around 1994-95, when it was named Windows Commander. Since that time, I was using it pretty much every day (except few short periods I was working exclusively on Unix). I still use it every working day (as I often spend weekends on Mac platforms).\n","title":"Total Comander version 7.01 final is out","type":"post"},{"content":"Thanks to long weekend and more quiet time in last couple of days (Happy 140th Birthday, Canada!), I managed to read something else than Ruby-ism/Rail-ism. Among others, I finished the Dreaming in Code by Scott Rosenberg, a book promising to explain why software is hard.\nIt is pretty tough question to answer. The way this books tries to address it is following the story not very well known open source project named Chandler through it's beginning over period of 3 years. Chandler was - and still is - developed by the OSAF - Open Source Application's Foundation, founded (and financed) by Mitch Kapor, who was before the founder of Lotus Development Corporation and designer of the \"Ur-spreadsheet\" Lotus 1-2-3.\nThe Chandler project - unlike most opensource projects was blessed - or cursed - by very solid financial backing, which allowed to hire fairly large team for fairly long time, without worrying too much about running out of time or out of money. It also contributed to quite ambitious goals (\"Outlook killer\") and to lot of time being allocated and spent on design and research projects (known also as BDUF - Big Design Up Front antipattern).\nFor me personally the most interesting discovery from reading the book was how similar can be the issues in two completely different projects that lacks clearly defined goal and requirements. In Chandlers case, the basic design questions were open for unhealthy long time: what is the platform for the repository ? Is it going to be peer-to-peer system or using centralized server ? What is the proper set of features ? How the user interface would look like ? I found these questions so familiar and reminded me of one other (non-opensource) project ...\nThroughout the book, you can find lots of quotations, observations and pieces of wisdom related to our profession collected from variety of sources - books, interviews, Web. For illustration few of them:\n\"Joy is an asset. It may well turn out that one of the most important effects of open source's success will be to teach us that play is the most efficient mode of creative work\" Eric Raymond\n\"In science, the whole system builds on people looking on other people's results and building on top of them. In witchcraft, somebody had a small secret and guarded it ... Traditional software is like witchcraft ...\" Linus Torvalds\n\"In any project that is introducing new technology or design ... plan to throw one away, because you almost certainly won't get it right for the first time\" Frederick Brooks\n\"... we should train developers the way we train creative people like poets or artists.... They study great works of poetry. Do we do that in our software engineering disciplines ? No. You do not look at the source code for great piece of software. Or look at the architecture of great pieces of software. You do not look at their design ...\" Richard Gabriel\nConclusion: Maybe not as easy read as originally expected - mostly because of the length and level of details related to Chandler, but nevertheless worth reading by all means. If you are professionally involved in building software for living, this books outlines many issues of the field. You may even have feeling terribly strong deja-vu (if you are around for couple of years/decades). Or - if you are younger - it can be a great example of things to avoid :-)\nRecommended.\n","date":"July 2, 2007","externalUrl":null,"permalink":"/posts/2007-07-02-book-review-dreaming-in-code/","section":"Posts","summary":"Thanks to long weekend and more quiet time in last couple of days (Happy 140th Birthday, Canada!), I managed to read something else than Ruby-ism/Rail-ism. Among others, I finished the Dreaming in Code by Scott Rosenberg, a book promising to explain why software is hard.\nIt is pretty tough question to answer. The way this books tries to address it is following the story not very well known open source project named Chandler through it's beginning over period of 3 years. Chandler was - and still is - developed by the OSAF - Open Source Application's Foundation, founded (and financed) by Mitch Kapor, who was before the founder of Lotus Development Corporation and designer of the \"Ur-spreadsheet\" Lotus 1-2-3.\n","title":"Book review: Dreaming in Code","type":"post"},{"content":"An interesting article on JavaLobby caught my eye today: Do .NET Applications Run Better on Java?\nNormally, knowing the not exactly impartial focus of the Java centric site such as JavaLobby or theserverside.com, one should be careful when reading how much Java outperforms .NET. The bias works the other way too - just look at the Theserverside.net or other .NET centric side how much is C# superior :-). With that in mind, I looked at the technical report.\nThe report was produced by Mainsoft, the company behind the cross compiler product MainSoft for Java EE. The crosscompilation means that the C# or VB.NET code is first compiled into CLR bytecode using standard Microsoft tools and then transformed into Java bytecode using the CLR byte as input. The study was based on fairly large project - 260'000 lines of code. The published result show that translated code running on Java VM and Websphere platform outperformed the .NET stack on both Windows as well as Linux platform.\nSo far so good. I have no plan to question the results of the test. One could argue that because the evaluation was not done by independent third party, but by the authors of the crosscompiler, the result must be like it was - simply because if the measurement would show that .NET performs better, no report would be published :-)\nFirst of all \"faster\" does not really means much faster. The speed increase measured is 8% in throughput and very much the same for requests per second. 8% increase is much too small to suggest doing anything major with the application, certainly not re-platforming ...\nSecond, comparison based on single port of an application proves absolutely nothing about results of repeating same process for other application or even every application. It can be indication of reality as easy as an exception. I am pretty sure that given the chance to respond, Microsoft or some other party interested in the opposite outcome, could find a C# application that would perform worse after conversion.\nMore interesting questions is why would you want to do this - replace Win2003 + .NET CLR with some other operating system (Windows/Linux/something else) plus Java plus Websphere. Clearly, performance cannot be the reason - at least not based on this results.\nPrice is not a good reason either. From cost saving perspective, crosscompiling .NET application to run in Java under Windows makes no sense, because .NET runtime is part of Win2003 license and cost of the license is there in both cases. This leaves using Linux as platform (or some other free alternative). True, Linux is free - but support is not, neither is labor. In real life, initial costs of licenses are small compared to accumulated costs of supporting application in production - and professional support for Windows or Linux is comparably priced. Besides, I bet that savings gained from not paying for Windows license will not cover cost of Websphere license plus the Mainsoft Java EE Entreprise edition license. True, you could use free j2EE server just as Tomcat or Glassfish or JBoss with the free Grasshoper version of the crosscompiler - but you may not get the same performance numbers. I like Tomcat and use it all the time: it is nice, flexible, easy to configure - but, not the fastest servlet container out there (there must be a reason why did Mainsoft pick Websphere with their own enterprise version after all) ...\nWhat is the conclusion ? The article above and approach it describes can be a life saviour if you have lot's of .NET code and *must* for some real reason switch the platform. The reason may be technical - or not - just consider the magic Google did with Linux. The report does hint one possible good reason - moving your application from PC's to really big machine - multiprocessors (multi means more than 16 these days when desktop machines start getting quadcores ;-)) running Unix or mainframe. The report shows that AIX on Power5+ based system with 4 CPU did ~ 3400 requests per second whereas the PC based did 2335. This would be interesting if the comparison was fair - but it was not. The AIX had 32 GB RAM whereas PC (with Linux or Windows) had 2 GB and you can imagine the price difference in the hardware.\nBut if there is no really compelling business reason of switching platforms, sticking with Windows when you want to run .NET application may save you lot of work - and most likely some money as well.\n","date":"June 27, 2007","externalUrl":null,"permalink":"/posts/2007-06-27-net-on-linux-faster-than-on-windows-hmm/","section":"Posts","summary":"An interesting article on JavaLobby caught my eye today: Do .NET Applications Run Better on Java?\nNormally, knowing the not exactly impartial focus of the Java centric site such as JavaLobby or theserverside.com, one should be careful when reading how much Java outperforms .NET. The bias works the other way too - just look at the Theserverside.net or other .NET centric side how much is C# superior :-). With that in mind, I looked at the technical report.\n","title":".NET on Linux faster than on Windows ? Hmm","type":"post"},{"content":"One thing that is on my Someday/Maybe list for quite some time is to get some off-site storage for my digital images. They are reasonably safe on RAID-5 NAS with a copy on USB disk, but what is missing is off-site copy. At minimum, a remote backup, ideally with an UI resembling something like Aperture or Photoshop Elements or Shoebox: photo organizer with Web intefarce and remote storage. So that in addition to have offline backup I would have an option to work with images from any location.\nI looked on several sites - Flickr, Fotki, Picassa Web. I liked Picassa, but 1 GB storage space may be plenty to publish few sized-down galeries, but close to useless for archival. Who has less than 1 GB digital photos ? I need to upload about 50x more ... It looked pretty bleak - but then friend of mine made me aware of SmugMug. I was impressed with what I have read in service description and even more when I saw it working.\nIt is still not the 100% perfect solution for me - but it certainly is the best thing I have found so far. The presentation is beautiful, it is fast and pleasant for the visitor. Oh, did I mention UNLIMITED storage for very reasonable price - $39.95/year. Plus unlimited traffic ... And it is really fast.\nThe way how SmugMug organizes your images are galeries. Similar to filmrolls from iPhoto, every images belongs to exactly one gallery. You can organize your galleries to categories and subcategories. Based on EXIF information, SmugMug can provide you with timeline and access your images based on the capture or upload time. Within the gallery, you can use drag and drop to re-organize the order, or create the slideshows.\nSmugMug has attracted nice and healthy ecosystems of users and tools. In addition to default tools (such as mass uploaders), several user made tools are available.\nIt is not only nice and smooth UI that is worth admiring. One area where SmugMug really shines was support. I had some questions so I fired off an email on Sunday afternoon, not really expecting anything other than automated response until Tuesday. What happened was nicest customer support surprise I have experienced in last few months. In less than hour I had an answer from real human being - what a rare experience these days. This with combination with really nice application makes SmugMug stand above the crowd ;-).\nIf I could make any additions to improve this very nice application, here are my suggestions:\n1) Allow alias for images. In order for an image to appear in multiple galleries, it must be copied. There is a tool that makes the process manageable, but copying is confusing - why should two images exist with same file name ? It is essential to allow same image be \"member\" of multiple galleries without copying it\n2) Allow \"stacks\" - similar pictures on top of each other - with best on top and an option to \"explode\" and \"implode\" the stack\n3) Really useful would be \"smart galleries\" - picture appears in the gallery based on metadata, e.g. Nikon, Olympus\n","date":"June 25, 2007","externalUrl":null,"permalink":"/posts/2007-06-25-search-for-perfect-online-photo-storage/","section":"Posts","summary":"One thing that is on my Someday/Maybe list for quite some time is to get some off-site storage for my digital images. They are reasonably safe on RAID-5 NAS with a copy on USB disk, but what is missing is off-site copy. At minimum, a remote backup, ideally with an UI resembling something like Aperture or Photoshop Elements or Shoebox: photo organizer with Web intefarce and remote storage. So that in addition to have offline backup I would have an option to work with images from any location.\n","title":"Search for perfect online photo storage","type":"post"},{"content":"I have spent last two days (and few evenings before) playing with Rails and using Netbeans Ruby IDE. What a great experience ! Unlike before, it is so much easier to have really good debugger that allows put breakpoints not only into the Ruby code in controllers and model - but even into the RHTML view files !\nNetbeans team works hard on improving the tool. With latest build - 2434, I have noticed great addition - Rails console. The IDE had IRB window even before, but the environment did not load the Rails context and would not recognize e.g. ActiveRecord. Now with latest build, everything works like charm.\nUsing Rails and coding in Ruby is real pleasure and the only pain-point was (compared to using Eclipse with Java or Visual Studio 2005 with C#) unavailability of a really good IDE. Yes - I tried RadRails and RDT plugin, but they still need lots of improvement and are not (yet) in the same league. Netbeans Ruby IDE is right now very likely best available free environment for Ruby and Rails environment. It allows work with both Ruby and JRuby with or without Rails - what more can you want ;-) ?\nThanks, Sun and the Netbeans team !\n","date":"June 24, 2007","externalUrl":null,"permalink":"/posts/2007-06-24-netbeans-ruby-ide-great-tool-getting-even-better/","section":"Posts","summary":"I have spent last two days (and few evenings before) playing with Rails and using Netbeans Ruby IDE. What a great experience ! Unlike before, it is so much easier to have really good debugger that allows put breakpoints not only into the Ruby code in controllers and model - but even into the RHTML view files !\nNetbeans team works hard on improving the tool. With latest build - 2434, I have noticed great addition - Rails console. The IDE had IRB window even before, but the environment did not load the Rails context and would not recognize e.g. ActiveRecord. Now with latest build, everything works like charm.\n","title":"Netbeans Ruby IDE - great tool getting even better !","type":"post"},{"content":"The realization came over me with full force that a good part of the remainder of my life was going to be spent in finding errors in my own programs.\n-- Maurice Wilkes\nWhat is so worthy mentioning on this obvious stament, describing fate likely shared by many thousand or milions of software developers worldwide ? Not much, only the date. According this book (which is a pretty good read btw),\nSir Maurice came to the sad realization mentioned above in the year 1949.\nJust wondering - what have we learned since ?\n","date":"June 21, 2007","externalUrl":null,"permalink":"/posts/2007-06-21-quote-of-the-day-8/","section":"Posts","summary":"The realization came over me with full force that a good part of the remainder of my life was going to be spent in finding errors in my own programs.\n-- Maurice Wilkes\nWhat is so worthy mentioning on this obvious stament, describing fate likely shared by many thousand or milions of software developers worldwide ? Not much, only the date. According this book (which is a pretty good read btw),\nSir Maurice came to the sad realization mentioned above in the year 1949.\n","title":"Quote of the day","type":"post"},{"content":"As seen in the video at http://sciencehack.com/videos/view/IDT2RMJNvSA#searchkeywords\nThe source code:\nVery good explanation is in the video mentioned above. So far so good - unfortunately the technique, however cool it is, does seem to work in Firefox only. Or at least it does not work in the still most prevalent browser on the Net.\nHere is how it renders (properly) in Firefox (tested with 1.5)\nand here is how it looks in IE7:\n","date":"June 21, 2007","externalUrl":null,"permalink":"/posts/2007-06-21-adding-image-to-link-with-css-only/","section":"Posts","summary":"As seen in the video at http://sciencehack.com/videos/view/IDT2RMJNvSA#searchkeywords\nThe source code:\nVery good explanation is in the video mentioned above. So far so good - unfortunately the technique, however cool it is, does seem to work in Firefox only. Or at least it does not work in the still most prevalent browser on the Net.\nHere is how it renders (properly) in Firefox (tested with 1.5)\nand here is how it looks in IE7:\n","title":"Adding image to link with CSS only","type":"post"},{"content":"Today's blog of the day is not really a blog, but a screencast. Dedicated to Ruby on Rails, the Railscast offers (as of today) 46 episodes of short, targeted practical advice on various aspects of Rails development.\nUnlike some other screencasts who try to record the screen action as MPEG movie, this one is perfectly legible. In addition to the Rails enlightenment, you can also enjoy the speed and aesthetics of using TextMate - with many great Ruby editing shortcuts and beautiful OS-X typography.\nAvailable as subscription in iTunes - search for Railscast.\n","date":"June 19, 2007","externalUrl":null,"permalink":"/posts/2007-06-19-botd-railscast/","section":"Posts","summary":"Today's blog of the day is not really a blog, but a screencast. Dedicated to Ruby on Rails, the Railscast offers (as of today) 46 episodes of short, targeted practical advice on various aspects of Rails development.\nUnlike some other screencasts who try to record the screen action as MPEG movie, this one is perfectly legible. In addition to the Rails enlightenment, you can also enjoy the speed and aesthetics of using TextMate - with many great Ruby editing shortcuts and beautiful OS-X typography.\n","title":"BOTD: Railscast","type":"post"},{"content":"Judging by the number of hits, Joel (and myself) are not the only people who would like to see nicer, better and faster MSDN documentation. As a very nice surprise, some of the feedback came directly from the people than actually can do something about it - like Darren Parker from Microsoft and Anand Raman from the Sandcastle project. Rob Relyea suggested and interesting looking tool based on XAML.\nThanks everybody - it is always nice to find out that even really big companies listen to the developers and want to address the problems. It almost feels like OpenSource experience where (it was few years back) we have encountered an issue in one of many Java templating libraries, posted to discussion group a question and few hours + several emails later had patch for the bug from the library creator :-). But back to the topic.\nIn addition to the issues mentioned yesterday, I'd like to add few more suggestions:\n1) Multiple languages on the same page.\nIn theory, it sounds great to be able to select in which .NET language syntax I want to see the class, but .... In real life, we seldom switch languages. The project that starts as C# projects will stay C# project - and for several months the developers will not care about documentation in anything but C#, certainly not J# or Javascript ... For that reason, ability to dynamically switch languages is not really important. And who needs J#, anyway ;-) ? If there is one thing that should go to sub-pages, the \"other languages\" should be it.\n2) Visual organization\nSounds like minor problem, but it impacts usability a lot. Few examples: The icons in the first column can be safely dropped and free space better used to add the return type and parameters. Position in the inheritance tree and list of parent classes / implemented interfaces (hyperlinked) should follow. After that, the list of members - constructors, methods, properties etc, preferably in single page with links to detail page / code examples. Just compare the definition of DataSet in Mono documentation and in MSDN to see the difference.\n3) Postback behaviour\nFrames are old and out of fashion, but IMHO still best solution for some sort of tasks - such as documentation. One of killer features of frames is separate and independent reload of one frame while others keep the selection, scroll position etc. Why does the MSDN page - which uses frames - have to reload all of them ?\n4) URL's\nIn the spirit of REST, the URL should be descriptive and understandable. The MSDN URL's are not bad - take for example\nhttp://msdn2.microsoft.com/\nen-us/library/system.data.dataset(vs.80).aspx.\nI am not sure, however, what value adds embedding the VS version into URL. It may be sometimes interesting to see the changes between the 1.1 and 2.0 versions of the same class, but it would be cleaner to make the \"split\" at the top level ( e.g.\nhttp://msdn2.microsoft.com/\nen-us/library/2_0/system.data.dataset.aspx\n) and provide link from the 2.0 version of DataSet documentation to 1.1 / 1.0 version of the DataSet documentation. This is immensely usefull if you are porting the 1.1 application and need quickly review the changes.\n4) Breadcrumbs or Dynamic Menu or what the heck it is\nI mean this:\nThis is something that really should be reviewed, both from implementation and well as content perspective. As I see it - it tries to be several things at the same time and does not really do properly any of them. It duplicates part of the path in tree in left frame, interwoven with some other information.\nSome members of this construct are just plain confusing - for example Previous Version. Assume that I am on DataSet documentation and Click on Previous versions, it lands me either on starting page for .NET Framework 2.0 or 1.1 implementation. The problem is that NONE of these pages has anything to do with page I was on - the DataSet - and only way how to get back is Back button ...\nFrom usability perspective, selection in the \"menu\" often causes postback and redraw of all frames ...\nOne more thing: it is not really important (and it may not be a problem on Microsoft side), but the left-side tree does not load in Safari on Mac - not that there would be too many people reading MSDN documentation from OS-X platform ;-)\n","date":"June 15, 2007","externalUrl":null,"permalink":"/posts/2007-06-15-msdn-documentation-the-follow-up/","section":"Posts","summary":"Judging by the number of hits, Joel (and myself) are not the only people who would like to see nicer, better and faster MSDN documentation. As a very nice surprise, some of the feedback came directly from the people than actually can do something about it - like Darren Parker from Microsoft and Anand Raman from the Sandcastle project. Rob Relyea suggested and interesting looking tool based on XAML.\nThanks everybody - it is always nice to find out that even really big companies listen to the developers and want to address the problems. It almost feels like OpenSource experience where (it was few years back) we have encountered an issue in one of many Java templating libraries, posted to discussion group a question and few hours + several emails later had patch for the bug from the library creator :-). But back to the topic.\n","title":"MSDN Documentation - the follow up","type":"post"},{"content":"Did it ever happened to you that you were using some tool day after day - and never realized it's pretty big deficiencies ? Until somebody, coming from different background pointed out what everything is wrong with the tool ? Before that moment of revelation, the issues were just inconvenience, but right after that they became real annoyance ?\nExactly this happened to me last week and the credit for pointing out what is wrong with MSDN documentation (and the \"standard\" .NET documentation format in general) goes to Joel :-)\nFor developer using object oriented language such as C#, Java or Ruby, what you need on daily basis is to find information about a class, see its public interface,members, constructors, method signatures. Ideally, on single page, with possibility of drilling down to the details of a method and to a code example. You also very often need to see all implemented interfaces, have easy access to parent class and (in case of e.g. an interface inside a framework) to access the implementing classes or derived classes within this context.\nUnfortunately, the Microsoft .NET documentation makes this simple task not exactly easy, pleasant or fast. As an example, lets take something really simple e.g. DateTime struct. In the documentation, information about this simple class are separated to 6 pages: datetime structure itself, Members, Fields, Constructor, Methods and Properties. If you would expect that with this devotion of low level categorization the particular page for e.g. Methods will give you all details about all DateTime methods, you are wrong. What Methods page gives you is just list of names, not even a method signatures - parameter types and return values are missing. To get this information, you must click through into the page dedicated to that method. If the method is overloaded (take e.g. omnipresent ToString), the Methods page contains only one name and only the next page gives you the signatures, linked to another page with details. See for yourself\nIn addition to bad information structuring, almost every link causes full page reload.\nCompare with how much more usable is the Java documentation: it is very easy to see all interfaces, methods, constants, parent classes, implemented interfaces in single page. The dated frames-based UI actually makes lots of sense and is (except AJAX based dynamic site) much better way how navigate the documentation.\nWith all that said, I am not surprised that the tools such as Reflector are so extremely popular in .NET world. It not only provides very useful debugging/inspection tool, but thanks to excellent and compact presentation of information about the class retrieved from reflection, they are the fastest way how to get meaningful information on core classes API. Other than Reflector, the other fast way how to get information on .NET core library details is Google search.\nTry for example how fast you can access a documentation for particular class starting with Google search - let's take e.g. WebConfigurationManager. Google search returns blazingly fast (as always) - with the MSDN page as first hit. Now compare how fast you will get the same information starting from MSDN home page, (which is btw, advertising 'new and improved search and navigation'). Your mileage may vary, but I usually see 3-8 seconds delay in search response (compare to \u0026lt;0.5 sec for Google). Few seconds seems like no problem, but when you do it all the time, it easily becomes pretty annoying. Even more so when you realize that Google is searching WHOLE WEB, with content they do not own or control, only index and rank, whereas MSDN search is searching MSDN data repository, which is - however you measure it - by many orders of magnitudes smaller and Microsoft fully controls most of it's content.\nWhy cannot the largest and most powerful software company create documentation that is useful and usable ? Even the documentation for the OpenSource Mono project (port of .NET to Linux and other platforms) is *much* better than the original. See the class DateTime there for comparison: the menu is dynamic and does not reload page every time you click on a link, the methods have full signatures and everything is on single page with local links and only details are on second level page.\n","date":"June 14, 2007","externalUrl":null,"permalink":"/posts/2007-06-14-msdn-documentation-the-worse-in-class/","section":"Posts","summary":"Did it ever happened to you that you were using some tool day after day - and never realized it's pretty big deficiencies ? Until somebody, coming from different background pointed out what everything is wrong with the tool ? Before that moment of revelation, the issues were just inconvenience, but right after that they became real annoyance ?\nExactly this happened to me last week and the credit for pointing out what is wrong with MSDN documentation (and the \"standard\" .NET documentation format in general) goes to Joel :-)\n","title":"MSDN Documentation - the worst in class ?","type":"post"},{"content":"Today's Blog Of The Day is named Strange Maps, which strangely accurate name. If you have are into maps, or information visualization - or combination of both, do NOT visit this link, because you risk sticking there for few hours :-).\nSome ideas presented are quite original and wonderful: for example the map of the USA, having instead of names of the states name of the countries with same GDP as the state. You will find out that Canada == Texas, France == California and Hungary == New Mexico. Or a transposition of the map of Europe and map of Middle Earth - this places Rohan to southern Germany (not a bad match), Isengard is Hamburg. The Mordor ended up in Transylvania with Mount Doom in Romania, Minas Morgul in Hungary and Minas Tirith approximately in Austria.\nHighly recommended.\n","date":"June 12, 2007","externalUrl":null,"permalink":"/posts/2007-06-12-botd-strange-maps/","section":"Posts","summary":"Today's Blog Of The Day is named Strange Maps, which strangely accurate name. If you have are into maps, or information visualization - or combination of both, do NOT visit this link, because you risk sticking there for few hours :-).\nSome ideas presented are quite original and wonderful: for example the map of the USA, having instead of names of the states name of the countries with same GDP as the state. You will find out that Canada == Texas, France == California and Hungary == New Mexico. Or a transposition of the map of Europe and map of Middle Earth - this places Rohan to southern Germany (not a bad match), Isengard is Hamburg. The Mordor ended up in Transylvania with Mount Doom in Romania, Minas Morgul in Hungary and Minas Tirith approximately in Austria.\n","title":"BOTD: Strange Maps","type":"post"},{"content":"It has been quite some time since I used a Swing based Java application. Compared to beauty and close-to-native feeling of Eclipse based application, Swing just did not feel right - it looked differently and behaved a bit differently. For long time, my desktop was Swing-free (not counting the JDK demo). Not any more, though.\nWhat made me to reconsider, is new release of the Netbeans v 6. In the latest milestone builds (M6 to M9), Netbeans team built amazing Ruby development environment. Compared to Ruby plugin in Eclipse, it has way more functionality, better debugging, really impressive editing support and very cool Rails extensions. The full description of new features is here.\nBest way how to start is to download pre-built IDE (inluding Mac friendly packaging) from NBExtras and give it a try. I was quite impressed. On modern hardware, the IDE is very responsive and Ruby development in Netbeans is even more fun as usual. The only small annoyance is frequent redraws and \"flicker\" of GUI when running on Windows - but it is likely one of the issues that may go away in final release.\n","date":"June 11, 2007","externalUrl":null,"permalink":"/posts/2007-06-11-swing-ing-back-to-netbeans/","section":"Posts","summary":"It has been quite some time since I used a Swing based Java application. Compared to beauty and close-to-native feeling of Eclipse based application, Swing just did not feel right - it looked differently and behaved a bit differently. For long time, my desktop was Swing-free (not counting the JDK demo). Not any more, though.\nWhat made me to reconsider, is new release of the Netbeans v 6. In the latest milestone builds (M6 to M9), Netbeans team built amazing Ruby development environment. Compared to Ruby plugin in Eclipse, it has way more functionality, better debugging, really impressive editing support and very cool Rails extensions. The full description of new features is here.\n","title":"Swing-ing back - to Netbeans","type":"post"},{"content":"The wild ride is over and the city gets back to normal. I wish we had won the Cup, but - Ducks were playing pretty good and found what worked on our team. Thanks, Alfie and the Sens - for all the great moments. You were fantastic. There will be another season in few months and another chance to bring the cup home.\nOn the positive side - it is good to have 2-3 more free evenings a week, now - when there is again nothing on the TV :-). Time to start catching up with neglected podcasts, blogs and feeds.\n","date":"June 7, 2007","externalUrl":null,"permalink":"/posts/2007-06-07-game-over-back-to-business/","section":"Posts","summary":"The wild ride is over and the city gets back to normal. I wish we had won the Cup, but - Ducks were playing pretty good and found what worked on our team. Thanks, Alfie and the Sens - for all the great moments. You were fantastic. There will be another season in few months and another chance to bring the cup home.\nOn the positive side - it is good to have 2-3 more free evenings a week, now - when there is again nothing on the TV :-). Time to start catching up with neglected podcasts, blogs and feeds.\n","title":"Game over, back to business","type":"post"},{"content":"Despite pretty impressive battery life - which is btw *nowhere* in the range of advertised 7500 page turns - over period of few months I have noted that the charging of the reader behaves kind of funny. Sometimes, even after being plugged-in for 24 hours, the battery indicator stubbornly stays on two squares out of four. Other times, right after connecting, it jumps right to full charge.\nIt is hard to really measure these things as the battery depletion is very slow on reading and I do not really listen to music on this device (that's what iPods are for). I am not the only person who noticed this behaviour - Steve Gibson and Leo Laporte, who enhanced my favorite podcast Security Now! to be an unofficial eBook Sony Reader news exchange :-) have seen the same thing (search for Sony). Btw, Steve and Leo - thanks for doing the eBooks plugs - I appreciate that a lot ...\nOne possible explanation is that the problem is more in indication, not in charging. The software running the Reader (Linux) may get confused about what is the actual state of the battery - because even if the charge shows one half, it does not seem like the battery was indeed half empty.\nMaybe what would help is to create few charge-discharge cycles by running the MP3 player which should use the battery in matter of hours, not days. I will try it out when I get to it - unless the next software update fixes the flaw (if it indeed is a software problem).\n","date":"June 4, 2007","externalUrl":null,"permalink":"/posts/2007-06-04-strange-charging-behaviour-of-sony-reader/","section":"Posts","summary":"Despite pretty impressive battery life - which is btw *nowhere* in the range of advertised 7500 page turns - over period of few months I have noted that the charging of the reader behaves kind of funny. Sometimes, even after being plugged-in for 24 hours, the battery indicator stubbornly stays on two squares out of four. Other times, right after connecting, it jumps right to full charge.\nIt is hard to really measure these things as the battery depletion is very slow on reading and I do not really listen to music on this device (that's what iPods are for). I am not the only person who noticed this behaviour - Steve Gibson and Leo Laporte, who enhanced my favorite podcast Security Now! to be an unofficial eBook Sony Reader news exchange :-) have seen the same thing (search for Sony). Btw, Steve and Leo - thanks for doing the eBooks plugs - I appreciate that a lot ...\n","title":"Strange charging behaviour of Sony Reader","type":"post"},{"content":"There has been lots of interesting news related to Microsof and Ruby recently, mostly about DLR's support of dynamic languages. One of my favorite tech authors stirred the waters once again last Friday with an article that goes beyond this and tries to paint larger picture of the uneasy relation between Ruby platform, Agile movement, OpenSource Community and Microsoft.\nOne quote from the article:\nThe attitude to open-source is a large part of this problem. When Java appeared there were yawning gaps in its portfolio, and worse some dreadful standard tools in its API (visions of Entity Beans spring to mind). Those gaps and bad ideas were fixed by the open-source community. Ant gave us a build tool, EJB was displaced by Spring and Hibernate. .NET has also got its gaps, and again the open source community has stepped up to fill them. Yet Microsoft refuses to collaborate with these efforts, even seems to go out of its way to undermine them. I was particularly sickened by Microsoft's reaction to NUnit - an excellent XUnit testing tool, elements of whose design were lauded by Anders Hejlsberg at OOPSLA. Microsoft ended not just bringing out a competitive library, but deliberately making it incompatible. That's not the kind of reaction that encourages people to invest their time in the platform.\nThere has been many reactions, the most notable by Rocky Lhotka, Sam Gentile, Cory Foy. They do not necessarily agree with Martin Fowler (but quite often do), but mostly they do confirm, that there is indeed a problem with how to deal with Open Source. Microsoft on one side would like to be the center of grass-root movement, lead and inspire it and benefit from innovation coming from the masses - and at the same time keep full control over the community project's direction and code base. This is impossible, as other companies (like Sun) found out the hard way.\nUnlike the reactions above, there was also lots of very different reactions - as one could expect with such flame-baits in text :-) Like this one - proudly promising \"deconstruction\" of Fowler's article. The author even found in the article lots of between-the-lines meanings like:\n\"Fowler is, in almost as many words, claiming Ruby is not a language, but a religion. Complete with values (commandments), a community (church), and a priesthood (himself, among a few others). I had to pick myself off the floor the first time I read that. \" Strangely, even after re-reading the article, I did not see that. What I saw is confusion between the community passionate about platform or technology and a religion. Which only confirms that it is very hard for Microsoft's hardcore fans to understand how open source movement and communities work. I think that an unbiased reader can find the Aaron's article filled with more religious-like zeal than Fowler's:\n\"LINQ, Lambdas, Expression trees, WCF, Workflow, WPF, Silverlight (again), IronPython, IronRuby, holy !@#$. A loud yawn? From whom? Certainly not from my clients or colleagues, who are salivating over this stuff. LINQ, more than Ruby, more than Java, will change the way we code - no other language since Foxpro has had this level of support for set operations directly in the language (yes, I know people that still do Foxpro, and they are laughing their *!#es off at how LINQ is a reinvention of what they have been doing for 20 years, but I digress).\" Truly enough, there is merit to the statement that mixing SQL (or SQL like) code with language used to code the user interface (which in a nutshell is one the LINQ \"innovations\") has potential to change the way how we code. For the worse ...\nThe other caveat is that it already did happen few times - and latest incarnation of this masochistic coding practice is used a lot in the PHP camp. And before PHP - let me think: DBase ? FoxPro ? MS-Access ? SQL-C ? None of these is exactly major enterprise software platform today, right ?\nI also quite share the excitement for lambdas and other functional programming constructs, but do not quite get how should they be a LINQ or Microsoft's innovations - or innovations at all. Apart from the fact that languages such as Python, Ruby, Haskell do have very powerful functional programming support for like 10-15 years - and IMHO better one than C# or LINQ - all this goes back to Lisp, which will be celebrating 50th anniversary next year.\nBut it is not the technology that is main source of tension and controversy here. It is the relation between open source projects and Microsoft. This relation was always problematic one - which is one of the reasons why are there so relatively few thriving OSS projects on Microsoft based platform, considering the Windows domination (I do NOT say that there are few projects, I am saying that with Windows owning maybe 90% of installed PC base, there should have been many more MS toolset based opensource projects than there are).\nAs one the reactions on Fowler's article did put it: \"Microsoft consistently moves to take the air away from its competitors, and it views successful OSS as competition. If you ask me why my team at Oxygen uses MbUnit instead of MS Test, Castle instead of ObjectBuilder, NAnt instead of MSBuild, and Subversion and CruiseControl instead of Team System, there are a few reasons. The first set of reasons are the standard OSS arguments: control, community, fitness to purpose, and price. The second set of reasons boil down to me being pissed off that Microsoft is trying to suffocate these projects instead of supporting them.\"\nOur recent experience with last two large .NET projects confirms this findings - we ended up using NAnt rather than MSBuild, because it was much easier for us to enhance and extend it, using CC + CVS/Subversion + MbUnit rather that VSTS - as there was no appealing reason to justify the cost and overhead.\nAs long as this is reality, the strange relationship MS vs OSS will probably continue. Which is too bad - because pragmatic software developers need the MS platform and MS needs developers and thriving communities. The .NET is pretty decent development platform - the best we had on Windows in last 20 years. After developing for many years for Windows in C with Win32, C++ with MFC and ATL, COM and DCOM, VB and doing ASP Websites I really do value how huge improvement is C#, .NET and the VS2005. It is therefore very sad to read that people and teams who work on improving the tools for the platform are attacked, rather than supported by the platform owner. Or hear about legal threats and possible patents lawsuits against open source ...\nTo demonstrate how company cares for developers, shouting Developers, Developers, Developers does not really cut it - even if shouting is really loud and delivered by the CEO. Supporting and encouraging more really successful projects like DotNetNuke or Mono - or sites like CodePlex does.\n","date":"June 3, 2007","externalUrl":null,"permalink":"/posts/2007-06-03-martin-fowlers-article-on-ruby-and-microsoft/","section":"Posts","summary":"There has been lots of interesting news related to Microsof and Ruby recently, mostly about DLR's support of dynamic languages. One of my favorite tech authors stirred the waters once again last Friday with an article that goes beyond this and tries to paint larger picture of the uneasy relation between Ruby platform, Agile movement, OpenSource Community and Microsoft.\nOne quote from the article:\nThe attitude to open-source is a large part of this problem. When Java appeared there were yawning gaps in its portfolio, and worse some dreadful standard tools in its API (visions of Entity Beans spring to mind). Those gaps and bad ideas were fixed by the open-source community. Ant gave us a build tool, EJB was displaced by Spring and Hibernate. .NET has also got its gaps, and again the open source community has stepped up to fill them. Yet Microsoft refuses to collaborate with these efforts, even seems to go out of its way to undermine them. I was particularly sickened by Microsoft's reaction to NUnit - an excellent XUnit testing tool, elements of whose design were lauded by Anders Hejlsberg at OOPSLA. Microsoft ended not just bringing out a competitive library, but deliberately making it incompatible. That's not the kind of reaction that encourages people to invest their time in the platform.\n","title":"Martin Fowler's article on Ruby and Microsoft","type":"post"},{"content":"The support for using dynamic languages such as Ruby or Python to code ASP.NET pages was announced for future versions of ASP.NET in the ASP.NET futures.\nUnless I am mistaken, it means that we eventually will be able to write control event handlers in Python or even Ruby - which is certainly more fun than in VB.NET or even in C#, but is it really so important ?\nWhat would be *really* cool if the whole ASP.NET become more agile and more \"rail-ish\". To make overall architecture more flexible - such as departure from not very flexible page-centric architecture towards MVC and routing. Maybe some version of ActiveRecord ? Or even multiple (and pluggable) template languages ? That would be really something.\n","date":"June 2, 2007","externalUrl":null,"permalink":"/posts/2007-06-02-code-in-ruby-under-aspnet-coming-soon/","section":"Posts","summary":"The support for using dynamic languages such as Ruby or Python to code ASP.NET pages was announced for future versions of ASP.NET in the ASP.NET futures.\nUnless I am mistaken, it means that we eventually will be able to write control event handlers in Python or even Ruby - which is certainly more fun than in VB.NET or even in C#, but is it really so important ?\nWhat would be *really* cool if the whole ASP.NET become more agile and more \"rail-ish\". To make overall architecture more flexible - such as departure from not very flexible page-centric architecture towards MVC and routing. Maybe some version of ActiveRecord ? Or even multiple (and pluggable) template languages ? That would be really something.\n","title":"Code in Ruby under ASP.NET: coming soon ?","type":"post"},{"content":"With latest iTunes update, quite silently, a very nice new feature appeared. Apple started to offer for download lectures from many universities, with wide selection of topics: from environment through politics to mathematics and computer science. Most of the lectures are videos, but you will find also audio tracks - albeit for some topics, audio is quite problematic. Can you imagine doing e.g. differential equations in audio-only ?\nThe best feature - the lectures are free downloads. See more details here or on iTunes.\nI guess now I do have really compelling reason to buy a video iPod :-)\n","date":"June 1, 2007","externalUrl":null,"permalink":"/posts/2007-06-01-itunes-u-great-beginning/","section":"Posts","summary":"With latest iTunes update, quite silently, a very nice new feature appeared. Apple started to offer for download lectures from many universities, with wide selection of topics: from environment through politics to mathematics and computer science. Most of the lectures are videos, but you will find also audio tracks - albeit for some topics, audio is quite problematic. Can you imagine doing e.g. differential equations in audio-only ?\nThe best feature - the lectures are free downloads. See more details here or on iTunes.\n","title":"iTunes U: Great beginning","type":"post"},{"content":"Joel Oleson is suffering if you do not blog ! Sounds strange ? Read the article Join the SharePoint Blogging Revolution!\nat http://blogs.msdn.com/joelo/archive/2007/05/25/you-don-t-blog-i-m-suffering-because-you-don-t-blog.aspx\nHe makes several very good points - which have very little to do with Sharepoint - but I think the best one is helping the \"organic indexing\" of the Web space and helping the search engines out there better rank content. I wrote about this while ago.\n","date":"May 31, 2007","externalUrl":null,"permalink":"/posts/2007-05-31-why-blogging-is-important/","section":"Posts","summary":"Joel Oleson is suffering if you do not blog ! Sounds strange ? Read the article Join the SharePoint Blogging Revolution!\nat http://blogs.msdn.com/joelo/archive/2007/05/25/you-don-t-blog-i-m-suffering-because-you-don-t-blog.aspx\nHe makes several very good points - which have very little to do with Sharepoint - but I think the best one is helping the \"organic indexing\" of the Web space and helping the search engines out there better rank content. I wrote about this while ago.\n","title":"Why blogging is important","type":"post"},{"content":"It happened! After starting my preferred feed aggregator - Google Reader I have noticed the new feature that sounded so good that I almost could not believe it: offline reading. Using new plugin - Google Gears, the reader can cache 2000 items locally and allows you to go offline and read the news, blogs or whatever you have subscribed to absolutely anywhere.\nThe installation starts with this screen:\nand goes on with this:\nAfter browser restart, all magic is hidden under small greenish button next to Settings:\nPressing the button downloads the 2000 items. The download is very fast, on cable modem it takes about 10-15 seconds.\nAfter download, you can disconnect the cable, switch off the wireless - or whatever you do - and take your latest and greatest blogs and news wherever you want. Here is the link to the \"official\" blog announcement.\nThanks, Google - this is great feature !\n","date":"May 30, 2007","externalUrl":null,"permalink":"/posts/2007-05-30-reading-blogs-and-feeds-offline/","section":"Posts","summary":"It happened! After starting my preferred feed aggregator - Google Reader I have noticed the new feature that sounded so good that I almost could not believe it: offline reading. Using new plugin - Google Gears, the reader can cache 2000 items locally and allows you to go offline and read the news, blogs or whatever you have subscribed to absolutely anywhere.\nThe installation starts with this screen:\n","title":"Reading blogs and feeds offline","type":"post"},{"content":"\"Corporate IT is dominated by bloatware. Time and time again we have to deal with expensive software purchased on golf-courses that just get in our way while sucking funds and development hours. Technologies that make it harder for programmers to do what they like to do best - make a difference for the businesses they are supporting. \"\n-- Martin Fowler\n","date":"May 29, 2007","externalUrl":null,"permalink":"/posts/2007-05-29-quote-of-the-day-martin-fowler/","section":"Posts","summary":"\"Corporate IT is dominated by bloatware. Time and time again we have to deal with expensive software purchased on golf-courses that just get in our way while sucking funds and development hours. Technologies that make it harder for programmers to do what they like to do best - make a difference for the businesses they are supporting. \"\n-- Martin Fowler\n","title":"Quote of the day (Martin Fowler)","type":"post"},{"content":"A brief look at my Google Reader subscription list made me aware that I have added to my reading list a loooot of blogs, newslist and so on. Unfortunately, they are not organized very well and should be properly placed into folders. In a process of doing that, I will put some of the interesting blogs here.\nFor today, it is Frans Bouma's blog - focusing on .NET and Microsoft technology platforms. From the most recent good articles, look at why API's should not be designed by scientists - discussing and comparing various ways how the database level paging is handled in various databases (MySQL, PostgreSql, DB2, Oracle, SS2005), or read Frans' comments on Entity Framework being cut from .NET 3.5 - which is sad, but IMHO fairly accurate summary of the recent development. See for yourself.\n","date":"May 28, 2007","externalUrl":null,"permalink":"/posts/2007-05-28-botd-blog-of-the-day-frank-boumas-blog/","section":"Posts","summary":"A brief look at my Google Reader subscription list made me aware that I have added to my reading list a loooot of blogs, newslist and so on. Unfortunately, they are not organized very well and should be properly placed into folders. In a process of doing that, I will put some of the interesting blogs here.\nFor today, it is Frans Bouma's blog - focusing on .NET and Microsoft technology platforms. From the most recent good articles, look at why API's should not be designed by scientists - discussing and comparing various ways how the database level paging is handled in various databases (MySQL, PostgreSql, DB2, Oracle, SS2005), or read Frans' comments on Entity Framework being cut from .NET 3.5 - which is sad, but IMHO fairly accurate summary of the recent development. See for yourself.\n","title":"BOTD (blog of the day): Frans Bouma's Blog","type":"post"},{"content":"Flash based, allowing create simple structures like graphs, org-charts, system diagrams. Diagrams can be exported to XML and saved locally - or converted to JPG or PNG on-line. Nice Web2-ish look and feel.\nSee bubbl.us for more.\n","date":"May 27, 2007","externalUrl":null,"permalink":"/posts/2007-05-27-online-diagram-drawing-tool/","section":"Posts","summary":"Flash based, allowing create simple structures like graphs, org-charts, system diagrams. Diagrams can be exported to XML and saved locally - or converted to JPG or PNG on-line. Nice Web2-ish look and feel.\nSee bubbl.us for more.\n","title":"Online diagram drawing tool","type":"post"},{"content":"Wonderful thing about Firefox extensions is the autoupdate feature. Go to Tools-\u0026gt;Extensions, select Find update and for all installed extensions you get the latest and greatest .... usually.\nOne extension where the update did not work was the Del.icio.us button for Firefox. I was happily using version 1.2 of the plugin and would never found out about the update, if I had not set the new workstation. The latest version 1.5.29 did not show in the updates. Which is too bad, because it is so much better ...\nNew extension gives you new menu item and sidebar, with two panels: tags and bookmarks. The tags are interconnected, for example, if you have bookmark tagged as '3d' as well as 'animation', you will see animation as child of 3d tag as well as 3d as child of animation. Tags can be sorted by alphabet or by frequency, bookmarks by last added, site, most visited, last visited.\nComplete tutorial is here. If you are still using the previous version, go ahead and upgrade - by uninstalling the old version and installing new from here. It is absolutely worth it.\n","date":"May 25, 2007","externalUrl":null,"permalink":"/posts/2007-05-25-new-version-of-delicious-extension-for-firefox/","section":"Posts","summary":"Wonderful thing about Firefox extensions is the autoupdate feature. Go to Tools-\u003eExtensions, select Find update and for all installed extensions you get the latest and greatest .... usually.\nOne extension where the update did not work was the Del.icio.us button for Firefox. I was happily using version 1.2 of the plugin and would never found out about the update, if I had not set the new workstation. The latest version 1.5.29 did not show in the updates. Which is too bad, because it is so much better ...\n","title":"New version of Del.icio.us extension for Firefox","type":"post"},{"content":"DHH is (obviously) David Heinemeier Hansson (the creator of Rails) and RIA (in this context) means Rich Internet Applications. And here is the quote:\nI think there's always room for new ideas, but I don't think that the whole fuss that's currently going on about RIA, rich Internet applications, is justified. I think we've been through this cycle so many times before that it in some ways amazes me how history seems to be ignored. We went through this with Java applets, they were going to rule the Web. Everything was going to be in a Java applet. HTML and CSS is history. And Flash came around, and Flash started focusing on applications. Now Flash is going to rule the Web and HTML and so on is yesterday. Now, Silverlight, Apollo, JavaFX, they're all bidding to take over the JavaScript, HTML and CSS [spaces], and I just don't buy it. I don't buy that developers by and large are going to jump into a proprietary technology and replace what HTML and CSS has given them.\nRead the full interview here\n","date":"May 24, 2007","externalUrl":null,"permalink":"/posts/2007-05-24-dhh-on-ria/","section":"Posts","summary":"DHH is (obviously) David Heinemeier Hansson (the creator of Rails) and RIA (in this context) means Rich Internet Applications. And here is the quote:\nI think there's always room for new ideas, but I don't think that the whole fuss that's currently going on about RIA, rich Internet applications, is justified. I think we've been through this cycle so many times before that it in some ways amazes me how history seems to be ignored. We went through this with Java applets, they were going to rule the Web. Everything was going to be in a Java applet. HTML and CSS is history. And Flash came around, and Flash started focusing on applications. Now Flash is going to rule the Web and HTML and so on is yesterday. Now, Silverlight, Apollo, JavaFX, they're all bidding to take over the JavaScript, HTML and CSS [spaces], and I just don't buy it. I don't buy that developers by and large are going to jump into a proprietary technology and replace what HTML and CSS has given them.\n","title":"DHH on RIA","type":"post"},{"content":"Found by accident - as usually - while searching for something completely different.\nVisuwords - visual dictionary, showing semantic relations between words.\nUniverse by Jonathan Harris.\nWikisky - detailed online sky map, showing the positions \u0026amp; basic characteristics of space objects using a Google Maps like interface.\nAnd two great videos: the 4 minutes video summary on what Web2 actually means and very funny presentation about PowerPoint presentations.\n","date":"May 23, 2007","externalUrl":null,"permalink":"/posts/2007-05-23-three-amazing-visualization-projects/","section":"Posts","summary":"Found by accident - as usually - while searching for something completely different.\nVisuwords - visual dictionary, showing semantic relations between words.\nUniverse by Jonathan Harris.\nWikisky - detailed online sky map, showing the positions \u0026 basic characteristics of space objects using a Google Maps like interface.\nAnd two great videos: the 4 minutes video summary on what Web2 actually means and very funny presentation about PowerPoint presentations.\n","title":"Three amazing visualization projects","type":"post"},{"content":"I found a handy T-SQL trick that helped to solve the following problem: during datawarehouse creation, we needed to consolidate multiple data sources from databases belonging to two generations of system: older one using int identity keys, the newer one, designed for replication and distributed data scenarios using GUID's as primary keys.\nIn the consolidated database, we needed to create single representation that would allow to store both new GUID based identities as well as old int-based keys. Direct conversion between UNIQUEIDENTIFIER type and int is not allowed. The following one liner will do the trick:\nCONVERT(UNIQUEIDENTIFIER, CONVERT(BINARY(10), 0) + CONVERT(BINARY(6), @id))\nThe \"fake GUID's\" it creates from integers are easy to identify as they have leading zeros. If you for any reason do not like it, replace the 0 in first convert with any suitable number.\n","date":"May 22, 2007","externalUrl":null,"permalink":"/posts/2007-05-22-unified-ids-for-legacy-database/","section":"Posts","summary":"I found a handy T-SQL trick that helped to solve the following problem: during datawarehouse creation, we needed to consolidate multiple data sources from databases belonging to two generations of system: older one using int identity keys, the newer one, designed for replication and distributed data scenarios using GUID's as primary keys.\nIn the consolidated database, we needed to create single representation that would allow to store both new GUID based identities as well as old int-based keys. Direct conversion between UNIQUEIDENTIFIER type and int is not allowed. The following one liner will do the trick:\n","title":"Unified ID's for legacy database","type":"post"},{"content":"Even with having Wiki as the main documentation repository, not all documentation ends up in a Wiki. Some documentation needs to be managed as part of the source tree - e.g. Readme's, compilation instructions and similar. This information is usually either plain text or in some form of text processor format, mostly Microsoft Word compatible. Both have their selection of problems. Word documents are large, bloated, harder to version controlled and not readable in shell environment (try to cat or tail Word document :-)). The plain text format lacks visual structure and without headlines, bold/italic, font sizes etc is harder read.\nSome projects I was working on were trying to use HTML as documentation format - but it was too hard to edit using \"programmers editors\" ... and HTML generated by MS-Word is not much better than binary format from readability and version management perspectives.\nOne format that works amazingly well is a plain text with Wiki markup structure. There is wide selection of various markups, the one I like the best is the Textile markup (which is implemented by many Wiki systems, including Confluence). Textile is very easy to remember, us natural to read and gives the document enough structure without being in the way. Using Textile as \"source markup\" allows us to copy and paste the document content directly to the Wiki, should it be required. Textile can be also very easily transformed to full fledged HTML using libraries available for all languages of interest (in my case - C#, Java, Python, Ruby - and hopefully will find something for Objective-C as well) to convert it to HTML.\nThe best feature of using Textile is that some editors - namely TextMate on Mac - support Textile natively and show headings and font attributes properly even without pre-processing step. And with Preview function even generate HTML right away. The similar can be done using plugin in JEdit as well as in Notepad++ with this syntax file.\n","date":"May 17, 2007","externalUrl":null,"permalink":"/posts/2007-05-17-using-wiki-markup-without-a-wiki/","section":"Posts","summary":"Even with having Wiki as the main documentation repository, not all documentation ends up in a Wiki. Some documentation needs to be managed as part of the source tree - e.g. Readme's, compilation instructions and similar. This information is usually either plain text or in some form of text processor format, mostly Microsoft Word compatible. Both have their selection of problems. Word documents are large, bloated, harder to version controlled and not readable in shell environment (try to cat or tail Word document :-)). The plain text format lacks visual structure and without headlines, bold/italic, font sizes etc is harder read.\n","title":"Using Wiki markup without a Wiki","type":"post"},{"content":"\"If it works, leave it alone — there's no need to understand it.\nIf it fails, try to fix it — there's no time to understand it.\"\n\"A one-question geek test. If you get the joke, you're a geek:\nSeen on a California license plate on a VW Beetle: 'FEATURE'...\"\n— Joshua D. Wachs, Natural Intelligence Inc.\n\"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.\" — Martin Golding.\n\"The only problem with troubleshooting is that sometimes trouble shoots back.\"\n\"Who is this general 'Failure' and why is he reading my disk ?\"\n\"If Python is executable pseudocode, then perl is executable line noise.\"\n\"The great thing about Object Oriented code is that it can make small, simple problems look like large, complex ones.\"\n\"C++: Hard to learn and built to stay that way.\"\n\"I invented the term 'Object-Oriented', and I can tell you I did not have C++ in mind.\"\n— Alan Kay, creator of Smalltalk\n\"There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence.\" — Jeremy S. Anderson.\n\"It is easier to port a shell than a shell script.\" — Larry Wall.\n\"Unix is user-friendly. It's just very selective about who its friends are.\"\n\"The number of the beast — vi vi vi.\"\nSoftware and cathedrals are much the same - first we build them, then we pray.\nIf a million monkeys were typing on computers, one of them will eventually write a Java program. The rest of them will write Perl programs.\nThe camel has evolved to be relatively self-sufficient. On the other hand, the camel has not evolved to smell good. Neither has Perl. -- Larry Wall\nPHP is a minor evil perpetrated and created by incompetent amateurs, whereas Perl is a great and insidious evil, perpetrated by skilled but perverted professionals.\nIt's not at all important to get it right the first time. It's vitally important to get it right the last time.\nAndrew Hunt and David Thomas\nSome problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. Laurence J. Peter\n","date":"May 15, 2007","externalUrl":null,"permalink":"/posts/2007-05-15-more-programming-quotes/","section":"Posts","summary":"\"If it works, leave it alone — there's no need to understand it.\nIf it fails, try to fix it — there's no time to understand it.\"\n\"A one-question geek test. If you get the joke, you're a geek:\nSeen on a California license plate on a VW Beetle: 'FEATURE'...\"\n— Joshua D. Wachs, Natural Intelligence Inc.\n\"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.\" — Martin Golding.\n","title":"More programming quotes","type":"post"},{"content":"After Adobe's Apollo and Microsoft's Silverlight, Sun has addes own version of scriptable, interactive platform named JavaFX. Unlike the previous three (Flash included), this is going to be Open Sourced - under the Microsoft's most hated license - GPL.\nNow the race to replace Flash really becomes really interesting ...\n","date":"May 12, 2007","externalUrl":null,"permalink":"/posts/2007-05-12-new-kid-on-the-block-in-race-to-be-flash-killer/","section":"Posts","summary":"After Adobe's Apollo and Microsoft's Silverlight, Sun has addes own version of scriptable, interactive platform named JavaFX. Unlike the previous three (Flash included), this is going to be Open Sourced - under the Microsoft's most hated license - GPL.\nNow the race to replace Flash really becomes really interesting ...\n","title":"New kid on the block in race to be Flash killer","type":"post"},{"content":"I am working on the BI modules for automotive data-analytics application these days. Which means that I am doing quite a bit coding and using T-SQL and in addition to Visual Studio 2005, I use quite often the Sql Server Management Studio for SQL Server 2005. In theory, both tools should be based on the Visual Studio IDE code base. Which is maybe true, but there are many quite annoying differences.\nSome of the differences is available featureset. I wish there was single tool that had all the database features of both: strong scripting capabilities of SSMS and much better development support with debugging in VS-2005. One can understand that the tools were meant to serve different audiences, but why not make the SSMS a lightweight, trimmed down version of VS2005 targeting database and OLAP projects only ?\nSome differences are really annoying though. One discovered today is related to GUID's. Take the code sequence\nDeclare @MyGuid\tuniqueidentifier\nset @MyGuid = NEWID()\nselect 'aaaaa', @MyGuid\nYou would expect that the result will be one row, consisting of value 'aaaaa' and some GUID, right ? Wrong. It is true only in SSMS as the picture shows:\nIn Visual Studio 2005 SP1, the result looks like this:\nwhich on one side announces 1 row in resultset, but does show the same result as if the resultset was empty. As we found out, the problem is related to displaying the GUID value - if your resultset does not contain it, the row will show OK. Same result can be achieved using explicit conversion, as shown in the picture:\n","date":"May 11, 2007","externalUrl":null,"permalink":"/posts/2007-05-11-differences-between-visual-studio-and-ssms/","section":"Posts","summary":"I am working on the BI modules for automotive data-analytics application these days. Which means that I am doing quite a bit coding and using T-SQL and in addition to Visual Studio 2005, I use quite often the Sql Server Management Studio for SQL Server 2005. In theory, both tools should be based on the Visual Studio IDE code base. Which is maybe true, but there are many quite annoying differences.\n","title":"Differences between Visual Studio and SSMS","type":"post"},{"content":"Since I got through \"Rails immersion\", I keep seeing the implementations of the same idea everywhere. Latest find is Subsonic, which implements Active Records in .NET space. Rather than writing more, see this screencast.\n","date":"May 9, 2007","externalUrl":null,"permalink":"/posts/2007-05-09-rails-ideas-everywhere/","section":"Posts","summary":"Since I got through \"Rails immersion\", I keep seeing the implementations of the same idea everywhere. Latest find is Subsonic, which implements Active Records in .NET space. Rather than writing more, see this screencast.\n","title":"Rails' ideas everywhere","type":"post"},{"content":"During last two weeks I have been reading and playing a lot with Rails. Now I am in the state where I think I started to \"get it\" and understand how things work under the surface. Which means I am ready actually start using the framework for real work and become proficient as I get my hands dirty.\nTo get to this state, absolutely essential and by far the best book is the classic one - Agile Web development with Rails co-authored by the original Rails designer and one of the Pragmatic Programmers. Like other books, the first part is sort of step-by-step code tutorial, which leads you through creation of a Rails application, shows you how you access data, create UI, use scaffolding, etc etc. Unlike other books, this does not stop there and the second part of the book is an excellent coverage of Rails internals - ActiveRecord, ActiveView and templating system. Very well written and offering great balance between covering important features without becoming reference manual.\nThe best feature of this and other Pragmatic books is that you can purchase it as e-Book in the PDF format (without any DRM restrictions, just customized with your name in text) which is cheaper, very portable :-) and very search-able. As added bonus, you get free updates when Rails changes or an error is discovered. As matter of fact, I just got such email, only few days after I bought the book.\nThe above book is not the only e-book I have purchased from Pragmatic Programmers. After 9 years, I have decided to buy a book covering such basic and boring thing as an editor. My previous (and first ever) book focusing on how to use an editor was \"Learning GNU Emacs\", back in 1998. You may say that if you need a book to use an editor, there must be something wrong with that piece of software. That is certainly one possible view. But the other explanation is that the editor is so powerful, extensible, customizable that it allows many ways how to be used and deserves the book. In my opinion, the later is very true about Emacs. I was using it for few years, but eventually switched back to Windows alternatives or IDE's such as Eclipse or Visual Studio.\nNow there seems to be another editor that has promise to be such great, powerful and extensible tool as Emacs was - but different way. It is TextMate - an editor available only on OS-X platform. I have got the license as part of the Mac Heist charity sale over Christmas and so far I was only scratching surface of its capabilities by using it similar way how I use Notepad++ on Windows. So I have decided to spend 20 bucks and few hours to \"unlock the power\" - editor is such basic tool used for hours every day that improving and optimizing your work habits actually can make a huge difference. Besides, TextMate is \"the editor\" for Rails development on OS-X and I am now in \"wow-phase\" of discovering the power of bundles. If you are on a Mac, give it a try - it is worth it.\n","date":"May 7, 2007","externalUrl":null,"permalink":"/posts/2007-05-07-best-book-for-ruby-on-rails/","section":"Posts","summary":"During last two weeks I have been reading and playing a lot with Rails. Now I am in the state where I think I started to \"get it\" and understand how things work under the surface. Which means I am ready actually start using the framework for real work and become proficient as I get my hands dirty.\nTo get to this state, absolutely essential and by far the best book is the classic one - Agile Web development with Rails co-authored by the original Rails designer and one of the Pragmatic Programmers. Like other books, the first part is sort of step-by-step code tutorial, which leads you through creation of a Rails application, shows you how you access data, create UI, use scaffolding, etc etc. Unlike other books, this does not stop there and the second part of the book is an excellent coverage of Rails internals - ActiveRecord, ActiveView and templating system. Very well written and offering great balance between covering important features without becoming reference manual.\n","title":"Best book for Ruby on Rails","type":"post"},{"content":"Imagine if somebody got copyright on a number 32. You could not say any more on a Web page that you use 32 bit OS because you were not allowed to use the number. You could not even write thirty two, or 0x20... Could not send a card for 32nd birthday. Sounds crazy, right ?\nBut exactly this is happening. Somebody is trying to claim exclusive ownership of one number and sending take-down letters, law threats to those you have it posted on their web sites or blogs.\nThis is so wrong. Nobody can restrict usage of a number. Any number. Numbers cannot be copyrighted. Not even primes. Not even a really big numbers. Not even the number, like 41425871524967055159433955941880327 * 320.\nNumbers are above politics and corporate lawyers. Above DRM and patents.\nNumbers are free speech. Maybe the last real free speech remaining ...\nIf the above does not really make any sense, maybe this and this will shed some light ...\n","date":"May 5, 2007","externalUrl":null,"permalink":"/posts/2007-05-05-its-all-about-numbers/","section":"Posts","summary":"Imagine if somebody got copyright on a number 32. You could not say any more on a Web page that you use 32 bit OS because you were not allowed to use the number. You could not even write thirty two, or 0x20... Could not send a card for 32nd birthday. Sounds crazy, right ?\nBut exactly this is happening. Somebody is trying to claim exclusive ownership of one number and sending take-down letters, law threats to those you have it posted on their web sites or blogs.\n","title":"It's all about numbers","type":"post"},{"content":"I had again the not-so infrequent pleasure of setting up fresh copy of Windows development stack. We were moving few machines between projects and to make sure that no forgotten source files are left on the harddisk, we reformatted and reinstalled Windows from scratch. It is usually good idea anyway, because developers like to install strange tools and utilities and generally customize machines to their own taste, which tend to be unique and is seldom shared.\nWe needed to set up usual development tools: Framework 2.0, Visual Studio, SQL Server 2005 with AS, as we will be doing few OLAP related modules. Plus Subversion client, some 3rd party tools (such as Notepad++, TotalCommander, Putty, Firefox with developers plugins) and so on. Not a rocket science, obviously - just needs to be done in proper order and not forget to include all needed components. If you install on Windows XP Pro, the usual catch is to forgot installing IIS first. Without IIS, the ASP.NET does not get configured out of the box and you have to register it manually by running aspnet_regiis.exe -i command, well hidden inside the Framework directory. Which is exactly what happened - on two machines, because both were imaged from same image, lacking the IIS component.\nSo we did the above step and afterwards one of the machines worked just fine, whereas the other kept throwing weird error on every attempt to debug an ASP.NET application with VS 2005. Now the fun began. The error message was a bit misleading - indicating that the problem is in running/attaching debugger on ASP.NET process. But even the access to ASP.NET application was broken, giving back 500 Server error and recommending to check event log. Which we did - and found absolutely nothing useful in there. After some digging, fruitless googling, checking the user membership in various groups and accounts under which the ASP.NET process was running ... the solution to the problem were directory permissions. On the machine which worked, the directory hosting Web app was writable by group Users. On the other it was not. Setting permissions that allowed ASPNET account read and write the directory fixed it all.\nSo what is my point and why am I documenting this fairly uninteresting issue ? Few points and observations actually. First, it would be very helpful if with such huge and complex tools as Visual Studio Microsoft would provide some checks and diagnostics that would indicate which parts of tools work and which do not work. The error messages should be much more detailed and provide some context about what went wrong. In Java world, having the stack trace in Tomcat log file would immediately clarify what can and what cannot be the cause. Using plain old text files for logging is probably better that stuffing everything into event log. Event logs may be great for system admins and remote access, but for developers, text file with meaningful content is more than adequate.\nSecond, the approaches that some people use when troubleshooting installation problem are unbelievable. Relying on Google results will often lead you in completely wrong direction. I was amazed how many crazy things were people trying to get rid of the error message as ours: \"What worked for me was to install framework 1.1, switch ASP.NET from 2.0 to 1.1 and then back\". One cannot exclude that this may have impact - and even fix the problem - but obviously, the fix is caused by some side effect which may or may not work on your machine. What is actually happening is people are trying to fix something they do not really understand, by attempting random actions and observing the impact. The problem may be in low experience level of the users - but also in bloated, messy environment of Windows system files components and their complex inter-dependencies. These two together create strange culture of frustrated users trying to catch black cat in dark room - and in half of the cases, the cat is even not there.\nLast but not least - without deep understanding what exactly gets installed where and how it depends on other components, you can be 100% sure what is the root cause of the problem - and where to look for solution. It would take us much less time to fix the issue if we were not try to fix assumably broken ASP.NET installation - because we knew we did skip one step, this was first thing to look at.\nThis is one thing where Java got it right - or at least much better than Windows. All you need to have is correct path settings (to include the version of JRE you want) plus JAVA_HOME variable pointing to it and rest is just making sure you have correct classpath that contains all jars. Adding components or plugins is matter of copying files to proper place, no installers and registry is involved. You can (and I do) have six different configurations and versions of Eclipse on your harddisk: one barebone, to test the new plugins, one with MyEclipse IDE, one with Web Tool Project, one with Ruby Development tools and RadRails (all 3.2 based), plus old 3.0 version to support older projects. I also do have three different installation of Apache Webservers - version 1.x, version 2.x and the \"portable\" version inside XAMP without any issues at all. Not speaking about approximately 5 versions of Tomcats and few other J2EE servers coexisting peacefully ...\nNow just try to install and run side by side just two installations of VS2005 with different set of plugins - and compare the experience. Your best bet is run two full Windows installations inside VM or using two workstations ...\n","date":"May 3, 2007","externalUrl":null,"permalink":"/posts/2007-05-03-fixing-broken-windows-development-environment/","section":"Posts","summary":"I had again the not-so infrequent pleasure of setting up fresh copy of Windows development stack. We were moving few machines between projects and to make sure that no forgotten source files are left on the harddisk, we reformatted and reinstalled Windows from scratch. It is usually good idea anyway, because developers like to install strange tools and utilities and generally customize machines to their own taste, which tend to be unique and is seldom shared.\n","title":"Fixing broken ASP.NET development environment","type":"post"},{"content":"at least as the programming language languages are concerned. One of the things that will be presented on the MIX07 is Dynamic Language Runtime, a new platform suitable to host high level, dynamic languages such as Python and Ruby. For Python, there is already pretty decent .NET implementation - namely IronPython. What is coming now is IronPython 2.0 based on the DLR as well as - yesss - IronRuby.\nIt is great that this is happening. In Java world, JRuby is very close to being full implementation of the language. The speed of the JRuby is still not quite in the proximity of the C implementation, but the large selling point of JRuby is its capability of deploying Ruby application (or even a Rails application) inside Tomcat or any other Java Web container. This removes largest obstacle of using Ruby in enterprise environment - namely being \"new\" and not approved platform. When the .NET runtime will be able to host Ruby code, acceptance in enterprise space will be even higher.\nIt is interesting how many news related to Ruby and Rails I see lately. One explanation is a new car owner syndrom. When you buy a new car, you start notice that many more people must have done the same thing because there are suddenly lots of cars of same make and model around you. In reality - there is about the same number of your car's instances in circulation as before, just your attention is now focused and you start to see them, where before they went unnoticed.\nBut the other explanation is that maybe, maybe there is really something changing :-). Would not it be great ?\n","date":"May 1, 2007","externalUrl":null,"permalink":"/posts/2007-05-01-microsoft-is-getting-more-dynamic/","section":"Posts","summary":"at least as the programming language languages are concerned. One of the things that will be presented on the MIX07 is Dynamic Language Runtime, a new platform suitable to host high level, dynamic languages such as Python and Ruby. For Python, there is already pretty decent .NET implementation - namely IronPython. What is coming now is IronPython 2.0 based on the DLR as well as - yesss - IronRuby.\nIt is great that this is happening. In Java world, JRuby is very close to being full implementation of the language. The speed of the JRuby is still not quite in the proximity of the C implementation, but the large selling point of JRuby is its capability of deploying Ruby application (or even a Rails application) inside Tomcat or any other Java Web container. This removes largest obstacle of using Ruby in enterprise environment - namely being \"new\" and not approved platform. When the .NET runtime will be able to host Ruby code, acceptance in enterprise space will be even higher.\n","title":"Microsoft is getting more dynamic","type":"post"},{"content":"Repository of presentations - http://www.slideshare.net/ on variety of topics.\nSpecialize code-only search engine: http://www.krugle.com/\nNew Google product on vertical search - Google Co-op.\n","date":"April 30, 2007","externalUrl":null,"permalink":"/posts/2007-04-30-few-interesting-links/","section":"Posts","summary":"Repository of presentations - http://www.slideshare.net/ on variety of topics.\nSpecialize code-only search engine: http://www.krugle.com/\nNew Google product on vertical search - Google Co-op.\n","title":"Few interesting links","type":"post"},{"content":"Running out of Security Now! and TWIT episodes, I have subscribed and started listening to few newly discovered podcasts.\nI have started to listen to the .NET specific one from Scott Hanselman named Hanselminutes. There are couple of factors that makes it better that other geeky blogs out there. First reason is the content quality. There is very high signal-to-noise ratio, pretty much all content counts and both guys in addition to being smart are quite good at achieving right balance between keeping on topic and spontaneity.\nSecond reason - it is not technology-religious and quite pragmatic. Scott obviously likes .NET and is passionate about Microsoft technologies - but there is no sucking-up, Scott is very open minded - just listen to the Dynamic languages where they talk about Ruby on Rails. He even owns a Mac and tests multiplatform software on multiple platforms :-)\nThird reason: there is PDF transcript available with lots of good links which would be otherwise lost (unless you listen with pen in your hand and in front of computer, and not driving or walking as myself.)\nAnd last but not least - very good audio quality, professionally recorded and processed. After listening to this episode about professional audio processing, it was clear why. Episodes are reasonably short - 20 to 40 minutes\nI have learned quite a lot from the about variety of interesting things - e.g that WPF/E (recently named Silverlight) may be actually something I really want to look at :-). It almost sounded too good to be true.\nSo if .NET is part of your world - or you want it to become part of your world - go for HanselMinutes.\n","date":"April 27, 2007","externalUrl":null,"permalink":"/posts/2007-04-27-new-great-podcast/","section":"Posts","summary":"Running out of Security Now! and TWIT episodes, I have subscribed and started listening to few newly discovered podcasts.\nI have started to listen to the .NET specific one from Scott Hanselman named Hanselminutes. There are couple of factors that makes it better that other geeky blogs out there. First reason is the content quality. There is very high signal-to-noise ratio, pretty much all content counts and both guys in addition to being smart are quite good at achieving right balance between keeping on topic and spontaneity.\n","title":"New great podcast","type":"post"},{"content":"","date":"April 27, 2007","externalUrl":null,"permalink":"/tags/podcast/","section":"Tags","summary":"","title":"Podcast","type":"tags"},{"content":"The natural gravity of our environment keeps pulling me out of scripting and Ruby world back to .Net zone :-). Out of curiosity, I looked into how easy or hard is it to access other database from Ruby, than the default MySQL which dominates all books, samples and tutorials.\nI have found three ways (at least), one likely platform independent and two Windows only. The platform independent requires module ADO.rb and works with the DBI interface. This sounds very similar to the way how Perl used to access databases, so I put this at the end of the list (some details are here). First Windows only methods used ODBC - no, thanks. Configuring machine specific data sources is not the way I wanted.\nThe best way was described in the Dave Mullet's blog and worked perfectly. I took the liberty to make the class better configurable - the result is published at code snippets.\nIf you do not know DZone Snippets, give it a look - it is best way how to share chunks of code that are too big to fit into blog (like one-liners or small functions) but not really a projects, which could be uploaded to SourceForge or CodePlex or similar open source repository. Snippets have coloring filter and tagging system - and the site is YACLRRW2C - yet another cool looking Ruby on Rails Web 2.0-ish creation ...\n","date":"April 25, 2007","externalUrl":null,"permalink":"/posts/2007-04-25-accessing-sql-server-2005-from-ruby/","section":"Posts","summary":"The natural gravity of our environment keeps pulling me out of scripting and Ruby world back to .Net zone :-). Out of curiosity, I looked into how easy or hard is it to access other database from Ruby, than the default MySQL which dominates all books, samples and tutorials.\nI have found three ways (at least), one likely platform independent and two Windows only. The platform independent requires module ADO.rb and works with the DBI interface. This sounds very similar to the way how Perl used to access databases, so I put this at the end of the list (some details are here). First Windows only methods used ODBC - no, thanks. Configuring machine specific data sources is not the way I wanted.\n","title":"Accessing SQL Server 2005 from Ruby","type":"post"},{"content":"If you've ever envied the ability of multilingual friends to bridge language gaps wherever they travel or gained new appreciation for your native language by learning a new one, then you can probably see the advantage of being a programming language polyglot. Developer polyglots travel the IT world more freely than do monolinguists (sure that they can apply their skills in any environment), and they also tend to better appreciate the programming language called home, because among other things they know the roots from which that home is sprung. Isn't it time you became a polyglot?\nFrom http://www-128.ibm.com/developerworks/library/j-ruby/?ca=dgr-jw22RubyOffRails\nI certainly feel like it which explains the recent ruby-esque and rail-ish diversions :-). To compensate the high level coding in Ruby, Objective C as next will bring me back down to the metal, I mean Core :-)\n","date":"April 24, 2007","externalUrl":null,"permalink":"/posts/2007-04-24-in-praise-of-the-polyglot/","section":"Posts","summary":"If you've ever envied the ability of multilingual friends to bridge language gaps wherever they travel or gained new appreciation for your native language by learning a new one, then you can probably see the advantage of being a programming language polyglot. Developer polyglots travel the IT world more freely than do monolinguists (sure that they can apply their skills in any environment), and they also tend to better appreciate the programming language called home, because among other things they know the roots from which that home is sprung. Isn't it time you became a polyglot?\n","title":"In praise of the polyglot","type":"post"},{"content":"As it happens, both my most favorite podcasters - Leo Laporte as well as Steve Gibson are passionate e-book readers. They have both purchased and are (mostly) happy users of the Sony PRS-500 aka Sony Reader in addition to several other platforms - (Palm, Pocket PC). In the latest podcasts - both in TWIT as well as Security Now!, the eBooks and eReader got quite some publicity :-).\nBoth had similar experience with PDF format on PRS-500 as myself - but Steve mentioned the PDF re-flowing the document to make it better suites for small screen - something I have looked into but did not get it working quite right. The preferred approach to using Reader is RTF format - which again, matches my impressions.\nNice discovery was that some independent sources - other than Sony store - are offering ebooks in LRF format. As an example see McCollum’s books - a hardcore, scientific sci-fi (no dwarves, elves, spells and dragons here :-)). Thanks for tips, gentlemen - I have added McCollum to my reading list.\n","date":"April 23, 2007","externalUrl":null,"permalink":"/posts/2007-04-23-one-more-reason-to-like-twit/","section":"Posts","summary":"As it happens, both my most favorite podcasters - Leo Laporte as well as Steve Gibson are passionate e-book readers. They have both purchased and are (mostly) happy users of the Sony PRS-500 aka Sony Reader in addition to several other platforms - (Palm, Pocket PC). In the latest podcasts - both in TWIT as well as Security Now!, the eBooks and eReader got quite some publicity :-).\nBoth had similar experience with PDF format on PRS-500 as myself - but Steve mentioned the PDF re-flowing the document to make it better suites for small screen - something I have looked into but did not get it working quite right. The preferred approach to using Reader is RTF format - which again, matches my impressions.\n","title":"One more reason to like TWIT","type":"post"},{"content":"(a followup to discussion last week)\nIn every outsourced software project you have four large areas: your customer, the business vertical you are writing software for, your implementation team and the technology foundation or platform you are using.\nTwo of these areas are on \"internal\" side of your organization (team and technology), two of them are on external - your customer side (business domain and customer organization). Two are more micro level in the sense that they have strong human interaction aspect (customer and team) and two are more macrolevel and less personal (business domain and technology). For that reason, you can represent these areas as quadrants using two axis micro/macro and internal/external: micro+internal = team, micro+external = customer, macro+internal = platform, macro+external = business domain.The degree of risk in the project is proportional to how many of these quadrants are actually unknown or new. Why is that ?\nHaving a new customer, you do not have established the communication channels, the degree of trust based on past successes is not there. You do not know the customer's corporate culture, internal structure, relations, influencers and inner politics that in theory should be completely irrelevant, but in reality may be one of the most disruptive discoveries. As one wise man said \"It is usually politics that gets you into troubles, very seldom technology\".\nStarting project with new, untested team, the team lead does not know what would be the best work division between the developers. Eventually, it can be discovered over time, but reshuffling the position has disruptive effect and usually requires some rework or refactoring. It is also very hard to make estimates as the team members productivity is unknown and does depend on the task.\nSwitching to new technology, obviously, you will have to incorporate some learning period and count on initial slowdown until everybody is as proficient in \"the new great thing\" as well as they were in the \"old boring one\" :-). This can be planned for and incoporated into project plan - or ideally, fixed before the project start on a prototype-slash-pilot project. Something you cannot really plan for is that you and your team may be confronted with unpleasant surprise late in the development cycle. The design or even the architecture may contain problems related to incomplete understanding of all aspect of used technology. As very good example is not so old DCOM and distributed applications developed using these technology. In development lab conditions, the applications work great, scale well, deployment is easy and running it is no-brainer. In real deployment scenarios where the fast LAN is replaced by VPN tunnels over internet and networking realities such as variable speed, reliability issues, latency, lots of firewalls etc, you have suddenly different picture. I still remember the fun of switching from C++ to Java back at the end of the last century - and few years later switching from Java to C#.\nThe new business area means that your company and development team enters an applications space in which you have not worked before: e.g. health, genetics, nanotechnology. This may create some communication issues between you and the client who is speaking the language you must first learn. The practical impact is that you do not know the existing solutions in the area, libraries, frameworks, tools available - and very easily you may find yourself reinventing the wheel.\nThe known/unknown is not a boolean variable, of course, more likely a number in range (let's say) 0 to 3, where 0 is perfectly known territory (like writing seventh Order Tracking system in J2EE, using again Struts and JSP). Number 1 represents some minor unknown areas (for example switching from Struts to Spring or from ASP.NET 1.1 to 2.0). Number two is major change in otherwise known area (like switching from ASP.NET to Winforms or to WPF - but still staying in .NET and C#) and number 3 is something completely new - e.g. Java team trying out Ruby on Rails.\nNow evaluate all four quadrant using this scale and add the numbers up to get the risk score. Starting project with risk score in two digits is either gamble or act of desperate measures - and chances of delivering high quality solutions addressing the requirements, on time and within budget are not great. The area between 7 and 9 is challenge zone - you have to expect bumpy ride, but once you do reach the target zone - oh boy, what a feeling. As side effect, when you succeed, usually you make huge progress in your delivery capabilities, team experience, customer trust level or both.\nThe 4 to 6 is healthy grow. There is very high level of confidence in the project outcome and still enough space to deal with unexpected, get the best out of the team and grow. This is where you want to be most of the time.\nThe 2-3 score is comfort zone - kind of routine, where you are sort of growing and evolving, but quite slowly. It can make sense under certain situations. I have seen this happening back in dot-com boom when one of our customers kept asking for more and more work on support for their large application that it saturated our delivery capability for quite some period of time. All we could do was hiring and training people as quickly as we could to keep up with the demand. But under normal circumstances, if you find yourself in this zone - wake up and make sure you do not slip into the \"binary\" zone, where all you to represent the uncertainty factor is single bit. Why ?\nBecause the levels of 0 and 1 are \"death by stagnation\". You do not want to be here. No change is bad. Having always same customer, same technology, same business area and stable, unchanging delivery team means that you are not growing: not getting new customers, not discovering new business areas, not keeping up to date with new technologies and not hiring. Definitely not having fun. With that, your skills portfolio will become obsolete and not challenged developers will look for more fun elsewhere.\n","date":"April 21, 2007","externalUrl":null,"permalink":"/posts/2007-04-21-four-quadrants-of-uncertainty/","section":"Posts","summary":"(a followup to discussion last week)\nIn every outsourced software project you have four large areas: your customer, the business vertical you are writing software for, your implementation team and the technology foundation or platform you are using.\nTwo of these areas are on \"internal\" side of your organization (team and technology), two of them are on external - your customer side (business domain and customer organization). Two are more micro level in the sense that they have strong human interaction aspect (customer and team) and two are more macrolevel and less personal (business domain and technology). For that reason, you can represent these areas as quadrants using two axis micro/macro and internal/external: micro+internal = team, micro+external = customer, macro+internal = platform, macro+external = business domain.The degree of risk in the project is proportional to how many of these quadrants are actually unknown or new. Why is that ?\n","title":"Four quadrants of uncertainty","type":"post"},{"content":"This week was full with attending the demos and workshops. On Tuesday, I spent half day on the Microsoft Unify Tour 2007. I planned to be there full day but an important business meeting made me change the plan. Fortunately, the sessions should be available recorded on the Web, so I will be able to check them later. The topic was bang-on - considering that we are in final phase of large project, using distributed network of SQL Server 2005 installations with replication and location was same as usual.\nThe format chosen for the presenation reminded reality show: introductory video and scripted/acted sequences of implementing the Web 2.0 enabled Web site. Two speakers - Christian Beauclair and Damir Bersinic were personifying the archetype of a developer (\".. sure it works. Just give me admin access to the PDC ...\") and a system administrator (\" .. sure we are aware that the patch XYZ is out since last month. We are evaluating it and eventually will deploy it in 2-3 months timeframe ... \") and walked the audience over very real-life like scenario. It turned up to be much better than one would expect - very convincing and often quite funny. I guess neither of them needed to act much - they just became what was their profession and passion before converting to techevangelism :-). For me personally, the IT-Pro part was more informative and the SCM 2007 looks like really nice piece of software worth looking at.\nAnd now for something completely different (as Monty Python's used to say): the second presentation I have attended this week (today) was on the alchemy business of open source business organized by OCRI. Couple of names caught my eye - e.g. Mike Milinkovich - executive director of the Eclipse Foundation, Dwight Deugo, assistant professor at the Carleton University and also of the Java Report fame. Too bad that the fame ended in 2001, Java report was the best Java and OOP oriented journal available. I have very high admiration for everything Eclipse and both these gentlemen were involved with the local Ottawa company which designed and created the first version of the platform - so I was curious to listen what they have to say.\nFrom other talks - it was interesting to see the Nortel Chief architect talking about open source. Large companies of the Nortel size have always had uneasy relation with open source software and it really depended on the team and local manager how much of the open technologies was allowed in. We were lucky, had great Nortel manager who understood the value and risks. As result, we were allowed to use what was right for the task and did some pretty amazing stuff with Enhydra application server, Freemarker and Jython back in 1999-2000.\nAnother surprise for me was Ingres. First of all, that it is still around - and according the the presenter, doing fairly well and growing. Secondarily, that Ingres was re-opensourced - started originally as opensource project back in 1980-ies, then was commercialized and closed, lost the lead against Oracle, IBM and Microsoft and found second life in re-opening the codebase. It was probably the only way - but I am not sure whether the world really badly needs another SQL database - with MySQL and Postgresql and few others already established and available, with larger mind-share and momentum ...\n","date":"April 19, 2007","externalUrl":null,"permalink":"/posts/2007-04-19-unify-tour-2007-and-open-source/","section":"Posts","summary":"This week was full with attending the demos and workshops. On Tuesday, I spent half day on the Microsoft Unify Tour 2007. I planned to be there full day but an important business meeting made me change the plan. Fortunately, the sessions should be available recorded on the Web, so I will be able to check them later. The topic was bang-on - considering that we are in final phase of large project, using distributed network of SQL Server 2005 installations with replication and location was same as usual.\n","title":"Unify Tour 2007 and Open Source","type":"post"},{"content":"YOU should write blogs. Even if nobody reads them, you should write them. It's become pretty clear to me that blogging is a source of both innovation and clarity. I have many of my best ideas and insights while blogging. Struggling to express things that you're thinking or feeling helps you understand them better.\nFrom http://steve.yegge.googlepages.com/you-should-write-blogs.\n","date":"April 18, 2007","externalUrl":null,"permalink":"/posts/2007-04-18-you-should-write-blogs/","section":"Posts","summary":"YOU should write blogs. Even if nobody reads them, you should write them. It's become pretty clear to me that blogging is a source of both innovation and clarity. I have many of my best ideas and insights while blogging. Struggling to express things that you're thinking or feeling helps you understand them better.\nFrom http://steve.yegge.googlepages.com/you-should-write-blogs.\n","title":"You should write blogs","type":"post"},{"content":"C++: an octopus made by nailing extra legs to a dog.\n(Steve Taylor).\nWhen C++ is your hammer, everything starts to look like your thumb.\n(Unknown author).\nI guess somebody got pretty fustrated with good ole C++ :-)\n","date":"April 15, 2007","externalUrl":null,"permalink":"/posts/2007-04-15-quote-of-the-day-7/","section":"Posts","summary":"C++: an octopus made by nailing extra legs to a dog.\n(Steve Taylor).\nWhen C++ is your hammer, everything starts to look like your thumb.\n(Unknown author).\nI guess somebody got pretty fustrated with good ole C++ :-)\n","title":"Quote of the day","type":"post"},{"content":"A friend sent me link two days ago making me aware that Mozilla decided to change the source code control system (= SCCS) they use. When such large and important project as Mozilla moves ahead and changes something so basic and fundamental to development as the SCCS, there must be good reason behind it. What was even more interesting was the system selected: no, it was not Subversion, but something much less established - Mercurial. Actually, until they selected it I was barely aware of its existence.\nFor many years, the synonym for Version Control was CVS. At least in the open source area and really large projects, CVS was the SCCS. Then things started to change and today if you look around in large open source projects, you will see that CVS and Subversion probably still lead but several really large projects are using very different tools e.g. Linux kernel is using Git.\nSo - is it time to review our technology toolkit in such basic tool as source code control ? Writing is on the wall - in one of the few remaining computer magazines in Chapters I glanced over today (forgot the name, something Linux related) - was a review of the current free version control systems. The article was comparing and evaluating RCS, CVS, Subversion, GIT, Bazaar, Monotone. In their evaluation the best marks were assigned to Subversion - it got 9/10 points. Mainly because ecosystem, support, documentation, user base and add-on/tools support. The next runner up was one of the new kids on the block - distributed version control system (DVCS) named Bazaar. Good old CVS ended up with 6 points and granddaddy RCS with 3/10.\nAmong the new tools, two important new trends are visible: new approaches to workflow by using distributed and decentralized VCS (= DVCS) rather than central server based and shift of the implementation platform from traditional very low level languages (C) and low level static languages (C++, Java) to dynamic and interpreted scripting languages.\nUsing dynamic, high level languages for the SCCS is natural result of increasing computing power of hardware - which makes speed and memory limitations disappear - as well as new, more complex usage scenarios which need more complicated software to address it. The dynamic languages such as Python or Ruby also have excellent support for networking and support most of communication protocols right out of the box and allow inherent portability between all supported platforms. This was often an issue for older systems written in C/C++. Bazaar - for example - is written in Python and can therefore runs on almost any platform.The shift towards decentralized and distributed systems is a logical continuation of the trend that started with abandoning the explicit (reserved) check-out mode of work. Anybody remembers the joys of Visual SourceSafe and issues when your colleague left for two weeks vacations and left checked-out few critical files ? In the systems using reserved checkout, every programmer had read-only copy of the code and could edit only files explicitly checked out - and checkout was limited to at most one person at any given time. The big change of CVS was allowing everybody having all code writable (in his/her own sandbox) and allowing parallel changes to the same file. The simultaneous changes from different people were merged using two step process - update (transfer the changes from repository to local sandbox) and commit - upload the local changes to single, central repository. The possible conflicts were resolved between update and commit.\nWhat is the fundamental difference between centralized and decentralized VCS ? In my limited understanding of how the DVCS work (as I have not worked with any of them yet on real project): unlike with CVS where there was one central repository and every developer had local copy of single state only (sandbox), with DVCS every developer has own copy of whole repository and therefore access to all versions of all files without depending on the centralized server. Every node is a repository and every commit is (or can be) local. Rather than synchronizing the local sandbox with the central repository, the independent repositories are synchronized. Nodes can synchronize directly as long as the changes are made available to other nodes by \"publishing\" them- usually using HTTP or SSH/FTP. The content of your repository will thus depend on number of nodes you synchronized with - and their own synchronization history.\nNew models of interaction are just one of the new features emerging. The DVCS can easily simulate workflows and processes from the traditional VCS but also allows several workflows impossible with VCS - like committing changes and getting differences without any connectivity to remote repository. (To be completely fair, you can do that to certain extent with Subversion - because latest status from repository is locally cached, you can always do diff and see local changes made - or undo them, but only for one revision). The DVCS is also very flexible - allows very dynamic creation of groups and branches and does not have single point of failure.\nSo what is the answer for the question from the title ? Should we throw away traditional VCS and start using new distributed decentralized tools ? I am not sure. With flexibility and freedom comes overhead and responsibility. Synchronizing large repositories can be expensive - both in time and network bandwidth. What is more important, it may require changes to the project management style and additional effort invested into keeping codebase under control - see the Development metodologies in Bazaar manual. When no repository is central, it is much harder to say where is the latest, most complete version of the system's code. And - unless you address it with your process - it may be hard to tell whether it is currently even available. The DVCS seems to make sense mostly when the team is very large and geographically distributed. I do not see many advantages for the smaller development team working in one location - other than fixing several CVS/Subversion annoyances and possibly providing better and easier merging. What is also important is tools availability and IDE integration. All this need to be better understood. Right now the answer for me to whether to switch: no. But to start looking into DVCS and evaluating to see the pros and cons - absolutely yes.\nNice comparison of features of the various SCCS is available here.\n","date":"April 14, 2007","externalUrl":null,"permalink":"/posts/2007-04-14-time-to-leave-cvs/","section":"Posts","summary":"A friend sent me link two days ago making me aware that Mozilla decided to change the source code control system (= SCCS) they use. When such large and important project as Mozilla moves ahead and changes something so basic and fundamental to development as the SCCS, there must be good reason behind it. What was even more interesting was the system selected: no, it was not Subversion, but something much less established - Mercurial. Actually, until they selected it I was barely aware of its existence.\n","title":"Time to leave CVS ?","type":"post"},{"content":"Another important step forward for all who are looking for alternatives to replace Outlook. With latest Thunderbird 2.0rc1 release it is now possible to add calendaring capability to Thunderbird (using the Lightning add-on) with Google calendar synchronization that works even with iCal invitations :-). Really nice.\nThe author's blog at http://bfish.xaedalus.net/?p=239 seems to be down, but cached version is available.\nCredits and thanks to Joel for finding it.\n","date":"April 12, 2007","externalUrl":null,"permalink":"/posts/2007-04-12-synchronizin-gcalendar-and-thunderbird/","section":"Posts","summary":"Another important step forward for all who are looking for alternatives to replace Outlook. With latest Thunderbird 2.0rc1 release it is now possible to add calendaring capability to Thunderbird (using the Lightning add-on) with Google calendar synchronization that works even with iCal invitations :-). Really nice.\nThe author's blog at http://bfish.xaedalus.net/?p=239 seems to be down, but cached version is available.\nCredits and thanks to Joel for finding it.\n","title":"Synchronizing GCalendar and Thunderbird","type":"post"},{"content":"It is a sad news - Kurt Vonnegut Jr., one of the great sci-fi writers, died at the age of 84.\nThanks for all the great hours spent reading many of great books he wrote over last 55 years. I guess that best way how to show respect is re-read something he wrote - like this one.\n","date":"April 11, 2007","externalUrl":null,"permalink":"/posts/2007-04-11-kurt-vonnegut-rip/","section":"Posts","summary":"It is a sad news - Kurt Vonnegut Jr., one of the great sci-fi writers, died at the age of 84.\nThanks for all the great hours spent reading many of great books he wrote over last 55 years. I guess that best way how to show respect is re-read something he wrote - like this one.\n","title":"Kurt Vonnegut - R.I.P.","type":"post"},{"content":"","date":"April 11, 2007","externalUrl":null,"permalink":"/tags/people/","section":"Tags","summary":"","title":"People","type":"tags"},{"content":"Goal is a dream with a deadline.\nFound on the Net - probably by Napoleon Hill\n","date":"April 10, 2007","externalUrl":null,"permalink":"/posts/2007-04-10-quote-of-the-day-6/","section":"Posts","summary":"Goal is a dream with a deadline.\nFound on the Net - probably by Napoleon Hill\n","title":"Quote of the day","type":"post"},{"content":"This was one great weekend ! Easter should be more often than once a year, I guess. Unlike Christmas, there was no shopping craziness before and much less overeating danger. Not counting overdose of chocolate, of course, but that's OK.\nI managed do mostly nothing for about one day - up to Friday evening. Then I dived into the Ruby and Ruby on Rails world. After reading this and one third of this book, I like Ruby even more. I actually did write some code - not much, but rewrote some of my old Python scripts I use to manage files and repositories. The new Ruby version is shorter and IMHO more elegant (even with my limited command of Ruby idioms), much better readable - albeit a bit slower than Python version. But that does not change my very positive impression of new language. In addition to these (and btw, the mixin's are so great it is even scary), I learned to love the Rake and gem tools. Gem is pre-packaged Ruby component, managed as unit, that can be installed and updated remotely using the gem tool. It solves the problem of versioning - something I wished Java had from the beginning. It also provide similar functionality as the GAC in .NET: allows side-by-side existence of multiple versions of the same component and makes component available to other programs. Very clever, very convenient. Same story as with the language - gem is something similar that Perl did have with CPAN, but it is just cleaner, nicer and polished ...\nRake is Ruby's own version of make (or Ant or msbuild if you wish). It uses DSL - domain specific language, similarly as Ant or make do, but the language is neither make-file based, nor XML based. It is high-level Ruby code, specifying the tasks, targets and dependencies - but in case you need it, full power of Ruby is available. Martin Fowler wrote a nice intro to Rake, see also this, this and Joe White's blog - on 'life, .NET and cats' - all great and worthy subjects :-)\nI have also discovered the lots of new powerful gems and Ruby based programs: for example another implementation of Cruise Control - not in Java or C#, but in Ruby (can be used to build anything, including Java or .NET), own version of Lucene named Ferret ...\nReal eye-opener was however Rails. It contains many excellent ideas that would make lots of sense in any environment - for example configuration free version of Hibernate, testing that goes way beyond unit test of business objects, clever way how to manage database schema versioning, lots of Spring flexibility in MVC processing - without Spring complexity. I am still learning and discovering new things, but as soon as I am comfortable enough with it, I will do a lunch-and-learn on Rails and specifically on these features that transcend the Ruby environment.\nAs I was reading, I kept adding bookmarks to my delicious account which now holds unbelievable 2110 links. In order to improve sharing the bookmarks, I have decided to create Thinknostic common bookmark repository where I could share the subset of the bookmarks using the 'My network' feature and for:SOMENAME labels. Thinknostic account is publicly accessible at http://del.icio.us/thinknostic\nIf you want to see what is there - just browse. We start small, rather than dumping all my bookmarks - I will be adding them as I review and clean up the taxonomy. Feel free to submit your recommendations - there is no need to change anything on you bookmarking habits - if you are using Del.icio.us. If not - consider giving it a try. There are many good reasons why this is a good idea - I tried to summarize them here:\nhttp://thinkwrap.wordpress.com/2007/01/08/dealing-with-digital-mess-bookmarks/.\nYou can contribute two ways:\na) if you want, you can become part of the Thinknostic \"bookmark club\" by adding thinknostic to your network\nb) whenever you find something of common interest, tag it (in addition to other tags that classify the link) by for:thinknostic (no spaces, one word)\nThe a) and b) are independent: you can suggest links regardless whether you are member of Thinknostic network of not ....\nWhen you label a bookmark with for:thinknostic, it will first appear in the Inbox and somebody with administrative access to the account will eventually move the link to the collection and possibly re-tag. More details onhow this all works are at: http://del.icio.us/help/\n","date":"April 9, 2007","externalUrl":null,"permalink":"/posts/2007-04-09-gems-and-bookmarks/","section":"Posts","summary":"This was one great weekend ! Easter should be more often than once a year, I guess. Unlike Christmas, there was no shopping craziness before and much less overeating danger. Not counting overdose of chocolate, of course, but that's OK.\nI managed do mostly nothing for about one day - up to Friday evening. Then I dived into the Ruby and Ruby on Rails world. After reading this and one third of this book, I like Ruby even more. I actually did write some code - not much, but rewrote some of my old Python scripts I use to manage files and repositories. The new Ruby version is shorter and IMHO more elegant (even with my limited command of Ruby idioms), much better readable - albeit a bit slower than Python version. But that does not change my very positive impression of new language. In addition to these (and btw, the mixin's are so great it is even scary), I learned to love the Rake and gem tools. Gem is pre-packaged Ruby component, managed as unit, that can be installed and updated remotely using the gem tool. It solves the problem of versioning - something I wished Java had from the beginning. It also provide similar functionality as the GAC in .NET: allows side-by-side existence of multiple versions of the same component and makes component available to other programs. Very clever, very convenient. Same story as with the language - gem is something similar that Perl did have with CPAN, but it is just cleaner, nicer and polished ...\n","title":"Gems and bookmarks","type":"post"},{"content":"I have decided to take weekend off. No catching up, no work, no stress. And it will be a proper weekend - 4 days long in total because both Friday and Monday are statutory holidays in Thinknostic. Great opportunity to relax, decompress, catch up on some reading and audio books and do something fun. And maybe gettogether with friends and celebrate Vlad's birthday. After all, the 28H is not every year :-)\nToo bad that the weather does not play along, at least not so far. It is supposed to be fairly cold and wet, with some flurries and 1 cm of snow, so my plans of adding 20-30 of kilometers of walking are in danger. But as they say - if you do not like weather forecast in Canada, wait half an hour .... We will see.\nAs a plan B (if the weather does not improve), there is always my reading pile plus couple of newly loaded ebooks in my Sony Reader, Chapters and Safari Online books. Speaking of which, I have started to read the Ruby on Rails book on Safari and am pretty impressed ! Why did not I look into Rails thing earlier ?\n","date":"April 4, 2007","externalUrl":null,"permalink":"/posts/2007-04-04-long-weekend-coming/","section":"Posts","summary":"I have decided to take weekend off. No catching up, no work, no stress. And it will be a proper weekend - 4 days long in total because both Friday and Monday are statutory holidays in Thinknostic. Great opportunity to relax, decompress, catch up on some reading and audio books and do something fun. And maybe gettogether with friends and celebrate Vlad's birthday. After all, the 28H is not every year :-)\n","title":"Long weekend coming","type":"post"},{"content":".NET 2.0 offers very rich and nicely designed library of core data structures, collections and algorithms. Occasionaly, you run into situation when you need something not in there. Before starting to design you very own extension of LinkedList or HashTable, look into interesting open-source project NGenerics - chances are you will find it there.\nIt contains quite a few new data structures:\nAssociation Bag BinaryTree BinarySearchTree Deque GeneralTree Graph HashList Heap Matrix ObjectMatrix PascalSet PriorityQueue ReadOnlyPropertyList RedBlackTree SkipList SortedList extensions of existing data structures to work with Visitor pattern\nVisitableHashTable VisitableLinkedList VisitableList VisitableQueue VisitableStack and implementation of algorithms - sorting:\nBubble Sort Bucket Sort Cocktail Sort Comb Sort Gnome Sort Heap Sort Insertion Sort Merge Sort Odd-Even Transport Sort Quick Sort Selection Sort and general:\nDjikstra's Single Source Shortest Path algorithm Euclid's Algorithm Fibonacci number generation. Prim's Minimal Spanning Tree Algorithm Nicely written, documented, comes with unit tests :-) and under very liberal license.\nSee also author's blog and the article on Codeproject he wrote. Thanks Riaan, your code is appreciated.\nBtw, speaking of Fibonacci, did you know Fibonacci was only his nickname and the real name of this Italian mathematician was Fibbooonnnnnaaaaaaaaccccccccccccciiiiiiiiiiiiiiiiiiiii ? :-)\n","date":"April 2, 2007","externalUrl":null,"permalink":"/posts/2007-04-02-very-useful-data-structure-and-algorithms-library/","section":"Posts","summary":".NET 2.0 offers very rich and nicely designed library of core data structures, collections and algorithms. Occasionaly, you run into situation when you need something not in there. Before starting to design you very own extension of LinkedList or HashTable, look into interesting open-source project NGenerics - chances are you will find it there.\nIt contains quite a few new data structures:\nAssociation Bag BinaryTree BinarySearchTree Deque GeneralTree Graph HashList Heap Matrix ObjectMatrix PascalSet PriorityQueue ReadOnlyPropertyList RedBlackTree SkipList SortedList extensions of existing data structures to work with Visitor pattern\n","title":"Very useful data structure and algorithms library","type":"post"},{"content":"I guess it is too early to write any more systematic opinion about the language you know less than 10 days, but after reading the Programming Ruby 2nd edition (thank you, Safari Books) I have found out that I actually do like couple of Ruby features a lot. Your mileage may vary - what speaks here is my Java/C#/C++/C/Python/Perl background and bias. Here there are my favorite Ruby-isms (so far) in no particular order:\n- expressive power of the language - few lines can take you a long way\n- syntax that is nice and readable, with curly brackets allowed (but not required) and without names like __something__\n- classes and OOP are organic part of the language, not a hack on top of it - everything is a class\n- no need to explicitly declare self in each function or bless references\n- reflection which is so easy that it is almost funny - 1.class.methods - how many lines would that be in Java ? :-)\n- access level control that works, not underscore naming hacks\n- text processing power of Perl, without most of cryptic Perl features\n- right middle point between language style dictatorship of Python and anarchy of Perl\n- ability to send messages, not call methods :-) - reminds me of Smalltalk and Objective-C\n- almost everything I loved about Lisp is available again ...\n- multiple inheritance functionality without multiple inheritance mess - mixin's are fantastic\n- gem installer - it just works\n- documentation and unit tests are part of the system, not optional afterthought\nI have not really reached critical mass of Ruby lines written or read and have not looked into Rails framework everybody is crazy about. As a strange coincidence, on today's Mac User's group meeting Tobias Lütke did a presentation on their product Shopify, written in - surprise surprise - Ruby on Rails. Once again - I wish I had more time ...\n","date":"April 1, 2007","externalUrl":null,"permalink":"/posts/2007-04-01-couple-of-things-i-really-like-about-ruby/","section":"Posts","summary":"I guess it is too early to write any more systematic opinion about the language you know less than 10 days, but after reading the Programming Ruby 2nd edition (thank you, Safari Books) I have found out that I actually do like couple of Ruby features a lot. Your mileage may vary - what speaks here is my Java/C#/C++/C/Python/Perl background and bias. Here there are my favorite Ruby-isms (so far) in no particular order:\n","title":"Couple of things I really like about Ruby","type":"post"},{"content":"Today I have started the walking season 2007. I did some gentle preparation during the week - few short, 4-5 km strolls around the neighbourhood, but it was today when I really started. It was beautiful day in Ottawa - sunny, temperature around 8-10, so I took off and did 12 km loop through Westboro, down south and around Dow's Lake up to downtown. Just fantastic. The companion on the road were Security Now! - I was behind few episodes, but I managed to listen to almost full 3 episodes.\nInteresting one was about Spambots - fleet of Zombies, remotely controlled that are used to send out spam. Conservative estimates are that from around 600 milion PC's, about 150 millions are infected zombies - without their owner's knowledge or consent, of course.\nSteve was speaking about the way how to detect from email headers that the email was spoofed. Basically, what you need to investigate is where the chain of Received headers which contains IP address of the sender is broken - that determines the point where the spammer connected to some SMTP server and send out message, all other headers beneath can be spoofed. I know this is not best explanation, but it is pointless to rephrase what Steve explained very nicely - listen here or read the notes.\nSo while walking and listening that, I have got an idea - with all the social websites and Web2.0 communities there may are realistic way how to cut down the spam wave that is everywhere around us (it is estimated that over 80% of all email is spam).\nKey ingredients of the solutions are:\n1) - owners of the zombie machines who do not know about the \"service\" their PC's are providing. It is not easy to identify these machines and they may not know what to do\n2) - who suffer the spam effects (and should be motivated to fix it) are the ISP's of these zombie users, because it is their bandwidth and their IP ranges who get blacklisted\n3) - those who would happily cooperate is everybody who hates spam (all of us, minus the spammers) and would not mind to do something - as long as the participation would be easy ...\nWhat I was thinking about a Web site/ Web service - something like where you can forward the spam you get which ends in your Junk folder or bounces back to your address. The service would analyze the headers and extract the IP's of zombies - and keep building and maintaining the list. Extraction is not that hard and doable with nice Perl/Python/Ruby script :-). After a while, it would lead to a list of IP's with activity record attached to it (which would allow the IP to drop off the list) ...\nNow imagine that the ISP's could register themselves and enter the range of their IP's. They would get back subset of the Zombie list residing in their own address space - and deal with them - for example notify users, ask them to download some malware removal program or even sell some additional service. It clearly must be ISP to deal with the Zombie owners, because they are only one who has access to their identity and it is in their interest to limit amount of bad things origination from their network. It is not only about spam - infected machine that sends spam can as easily and likely be part of DDoS attack, which is quite different legal category of problems. Either way, at the end, the result would be less active zombies around.\nIf the really big email services such as GMail and Yahoo - or big cable/DSL providers would participate and supply their own filtered spam (or even filtered list of Zombie-candidates) the database would IMHO start to provide valuable data very soon.\nWhat do you think ?\n","date":"March 31, 2007","externalUrl":null,"permalink":"/posts/2007-03-31-walking-season-and-spam/","section":"Posts","summary":"Today I have started the walking season 2007. I did some gentle preparation during the week - few short, 4-5 km strolls around the neighbourhood, but it was today when I really started. It was beautiful day in Ottawa - sunny, temperature around 8-10, so I took off and did 12 km loop through Westboro, down south and around Dow's Lake up to downtown. Just fantastic. The companion on the road were Security Now! - I was behind few episodes, but I managed to listen to almost full 3 episodes.\n","title":"Walking season ... and SPAM","type":"post"},{"content":"Man lernt nie aus - as the German say - one never stops learning. Thanks to comment found on my blog I found out that there is very nice solution problem of disappearing emails (after you download it with one POP client, other POP client would not get it). It is even documented in GMail help:\nhttp://mail.google.com/support/bin/answer.py?answer=47948\u0026amp;topic=1556If you're accessing your Gmail using POP from multiple clients, Gmail's recent mode makes sure that all messages are made available to each client, rather than only to the first client to access new mail.\nRecent mode fetches the last 30 days of mail, regardless of whether it's been sent to another POP client already.\nIf you sign in to Gmail using your Blackberry, you're signed in to recent mode automatically. For all other POP clients, replace 'username@gmail.com' in your POP client settings with 'recent:username@gmail.com'.\nThanks to unknown reader who made me aware of it.\n","date":"March 30, 2007","externalUrl":null,"permalink":"/posts/2007-03-30-how-to-access-gmail-with-multiple-pop-clients/","section":"Posts","summary":"Man lernt nie aus - as the German say - one never stops learning. Thanks to comment found on my blog I found out that there is very nice solution problem of disappearing emails (after you download it with one POP client, other POP client would not get it). It is even documented in GMail help:\nhttp://mail.google.com/support/bin/answer.py?answer=47948\u0026topic=1556If you're accessing your Gmail using POP from multiple clients, Gmail's recent mode makes sure that all messages are made available to each client, rather than only to the first client to access new mail.\n","title":"How to access GMail with multiple POP clients","type":"post"},{"content":"As Murphy said - you cannot do just one thing. Thanks to JDK 1.4 entering end-of-life support period (and 1.3 being unsupported for some time), we need to move few applications happily running on these antique Java platforms to at least Java 5 and gain few more years of uninterrupted Sun-supported life.\nUpgrading the applications was as expected, piece of cake - as long as you have solid build environment with build scripts and everything - which we certainly do. Ant runs on Java5 exactly as well as on 1.4 (maybe faster, but I did not measure), Tomcat was the same no-brainer thing and switching the Eclipse required only selecting different JRE in preferences window. Codewise, the only change required inside the application code was renaming few identifiers to something else than enum, which happens to be keyword in Java 5.\nSo far so good. What was not so easy were third party libraries. Our applications are using Jakarta Commons, Struts, Torque and few other great pieces of open source software. I like to compile everything from source, so I tried to rebuild 3rd party jar's. No luck - about one third did not compile (I have to remind you that these were versions from late 2001/early 2002). Unlike with our own code, it would make little sense try to change the 3rd party code - certainly not when there are many newer versions for each of the components already available anyway. Therefore - upgrading components is way to go. And here the fun begins.\nThe idea behind components such as Jakarta Commons is that they should be used in other components. And indeed - they are used. With little luck and enough components, you will end up with one jar being used/required by two, three or more other jars and over time, nice Web of inter-dependencies will somehow grow inside your little app. Nothing wrong with that. The trouble is that as the libraries mature and evolve, new versions are added, which add new features. In this process, sometimes the component's APIs are changed, some features are deprecated and eventually removed - and backwards compatibility slowly disappears. Because the different open source projects are evolving with various speed, you will eventually end up with requirements of two different and incompatible versions of the same component at the same time. This is usually not an issue when you are developing new project, because the time span is too short so that the differences in required versions are not very far apart. It does however cause problems when you are upgrading and working with enough components over a time span of several years.\nThere are two possible strategies: many small steps or one big jump. The small steps means that you try to upgrade as little as possible, keeping the changes in API minimal - just to achieve the goal (compilable with Java 5 in our case). The problem with this approach is that it is quite time consuming process, because of the cascading updates. Imagine e.g, that upgrading A1 to A2 requires upgrade of B1 to B2 (because A depends on B), but because B depends on C, you need also upgrade C1 to C2. And because the X also depends on B, after upgrading to B2 (unless you are lucky) you may be forced to upgrade X as well . It iterative \"snowball\" process and easily can take much longer than expected. Another problem is that after spending all that time, you have application that is still running on out-of-date components. Whether this is a problem or not, depends on number and size of business changes required.\nThe big jump strategy is to get the latest versions of everything. Chances are very high that it will compile and run OK - as long as all components are still active projects. The typical catch is that you have just updated the B1 to B7 and this is fine with all components except X, which was kind of dormant inactive project for last 3 years and still requires B3 as dependency. If the API of B3 and B7 differ enough, you may not be able simply use B7 without diving into unknown code and fixing it. The other catch is that your own application may be incompatible with latest components API of B7 and needs changes. This is better situation because you a) know the code b) it may be better code (if you did a good job) than the code of component X - but in both cases you may need to spend time on something that has no direct link to what you wanted to do in a first place: doing just that one thing :-)\n","date":"March 28, 2007","externalUrl":null,"permalink":"/posts/2007-03-28-upgrading-java-and-open-source-libraries/","section":"Posts","summary":"As Murphy said - you cannot do just one thing. Thanks to JDK 1.4 entering end-of-life support period (and 1.3 being unsupported for some time), we need to move few applications happily running on these antique Java platforms to at least Java 5 and gain few more years of uninterrupted Sun-supported life.\nUpgrading the applications was as expected, piece of cake - as long as you have solid build environment with build scripts and everything - which we certainly do. Ant runs on Java5 exactly as well as on 1.4 (maybe faster, but I did not measure), Tomcat was the same no-brainer thing and switching the Eclipse required only selecting different JRE in preferences window. Codewise, the only change required inside the application code was renaming few identifiers to something else than enum, which happens to be keyword in Java 5.\n","title":"Upgrading Java and Open Source libraries","type":"post"},{"content":"After almost two years of uninterrupted C# and .NET development, I have got back for few days to Java world. One of our old customers asked us to do few enhancements and changes in the application we wrote. And because we always stand behind our work, always do answer the call for help and do support our customers as long as they want to be supported, I have squeezed-in few days worth of work into pretty packed schedule. So here am I on a short detour into world of class files and jars ...\nThe application is based on Java and its roots are going back in 2001. It is Web application, using lots of open-source libraries: several Jakarta Apache Commons modules, Struts (in it's first incarnation), Freemarker, Apache Torque and JSP with Tiles. Everything running on Tomcat, built with Ant and developed with Eclipse.\nIt was such a great feeling to work with Eclipse again. It felt just right, right away - a nice, well polished, extremely user friendly and pleasant experience. So good that it caught me by surprise - what was it that caused this great feeling ? It was not about the language - I actually like C# (from a purely language perspective) maybe even better than Java, because the features allow more natural coding (like properties instead of getter/setter methods). It is certainly not the Java based web platform - using the combination of Struts tags with JSP 1.x is not any better than developing for ASP.NET, quite the opposite ... So it must be the IDE.\nThe problem of Eclipse in the past used to be memory requirements and speed. Thanks to hardware evolution and Vista hardware requirement push, typical today's machine is 2 GB, dual core box an on this box Eclipse is just flying. On the same platform, the Visual Studio 2005 does not have any issues either, but it just does not feel the same way. I really enjoyed small things in Eclipse - such as great and rich refactoring support (out of the box, without add-ons), helper methods (e.g. implement interface) and the way how the source code management systems are seamlessly integrated into the system. It is not that these features would be so special, unique and unavailable elsewhere - they are just done right.\nOne thing that I really admire about Eclipse (and wish I had it in VS 2005) is the \"fearless configurability\". I have had many times temptation to try out some new addin to VS, but did not do it just to avoid the possibilty that it could do something nasty to my development box, registry, Windows or all three of them. I just do not trust the installation programs that like to put strange DLL's into my Windows/System32 directory and write into registry.. In Eclipse, there is no install required - all you need is to unzip files into proper location and restart the IDE. The way how the platform work is very nicely designed and (after some learning period) actually very logical and quite transparent. I feel free to to try out everything I want. For example Ruby Development Tool plugin :-).\n","date":"March 27, 2007","externalUrl":null,"permalink":"/posts/2007-03-27-ode-on-eclipse/","section":"Posts","summary":"After almost two years of uninterrupted C# and .NET development, I have got back for few days to Java world. One of our old customers asked us to do few enhancements and changes in the application we wrote. And because we always stand behind our work, always do answer the call for help and do support our customers as long as they want to be supported, I have squeezed-in few days worth of work into pretty packed schedule. So here am I on a short detour into world of class files and jars ...\n","title":"Ode on Eclipse :-)","type":"post"},{"content":"There are few technical books which you enjoy first time you read them, remember the experience and keep coming back. One of such classic books is The Pragmatic Programmer - from journeyman to master - by David Thomas and Andrew Hunt. If you have not read it, get it, it is worth every cent. Since the book was written - ages ago, back in 2000 - it did not loose anything of its freshness and value - which one cannot say about most of technical books written earlier than 2-3 years ago. Inspired by the success of their initial creation, Dave and Andrew started the website and continued writing whole Pragmatic Programmer series of books.\nBook contains 46 tips and explanations and the tip #5 deals with knowledge portfolio - one of developer's main assets. Unfortunately it is expiring asset so you have to work hard to keep it recent and in good shape. Dave and Andy recommend using the same strategy as successful investors in finance markets:\ninvest regularly - even if small amounts, but create habit investing diversify to embrace change and to widen the reach manage risk - combine high-reward high-risk with low-reward low risk buy low, sell high - try to identify future hits before they become popular review and rebalance - what was true last year, can be different now They also recommend few practical steps and goals how to achieve the healthy and well balanced portfolio, such as:\n- learn new language every year\n- read a technical book every quarter\n- read nontechnical books too\n- participate in local user groups\n- experiment with different environments\nWhich got me thinking about how am doing wrt these suggestions. I guess I have no problem with \"read a book\" part, either technical or non-technical :-) - thanks to Safari I consume 1-2 technical books a month and thanks to e-books even more non-technical ones :-). What I have not done in about 3-4 years was learning a new language. I think I have not learned really new language since C# in 2002. One could argue that for Java programmer, C# is not really such a new language - in that case I have not really updated my language toolset since I started with Python back in 2000. That is terrible ! Obviously, some action is required - I am overdue at least with 4 new languages. Because it is highly impractical to tackle 4 problem at the same time, for this year I will be adding two.\nBut which programming languages ? Key here is the word pragmatic and the investment strategies above - more specifically, combining high and low risk, buying low and diversifying. I want to explore new territories, but stay away from esoteric and pure-research areas (e.g languages like Janus, Limbo or Concurrent Haskell :-)). After some research I picked two candidates: Ruby and Objective-C for the year 2007.\nThere are few reasons why exactly these two: they are both similar (with Smalltalk and functional programming/OO heritage) and opposite - one is multiplatform, interpreted, very high level, the other is (practically) single platform - OS-X language of choice, compiled and up to version 2.0 not even garbage-collector enabled. One has pretty clean and nice syntax, other is - well - simple, but quite ugly. And so on.\nI have started with Ruby yesterday - found a good book on Safari and started to read and play with the code. I will get back to it when my head stops spinning - and after I get some non-trivial programs done to get some real life feeling of the language. From the book reading point of view, it is pretty amazing what I have found in few hours :-).\nBtw, the version 1 of the Ruby boom by the same two authors is available online.\n","date":"March 25, 2007","externalUrl":null,"permalink":"/posts/2007-03-25-managing-knowledge-portfolio/","section":"Posts","summary":"There are few technical books which you enjoy first time you read them, remember the experience and keep coming back. One of such classic books is The Pragmatic Programmer - from journeyman to master - by David Thomas and Andrew Hunt. If you have not read it, get it, it is worth every cent. Since the book was written - ages ago, back in 2000 - it did not loose anything of its freshness and value - which one cannot say about most of technical books written earlier than 2-3 years ago. Inspired by the success of their initial creation, Dave and Andrew started the website and continued writing whole Pragmatic Programmer series of books.\n","title":"Managing knowledge portfolio","type":"post"},{"content":"\" ... the main reason why most software is not open-sourced is pure embarrassment ...\"\nLeo Laporte in Twit episode #90\n","date":"March 24, 2007","externalUrl":null,"permalink":"/posts/2007-03-24-thought-of-the-day/","section":"Posts","summary":"\" ... the main reason why most software is not open-sourced is pure embarrassment ...\"\nLeo Laporte in Twit episode #90\n","title":"Thought of the day","type":"post"},{"content":"Since yesterday, I made nice progress in solving my issues with content creation for PRS500 and it's readability. There are several ways how to proceed:\nThe simplest is to download Book Designer. It is free for non-commercial use and current version 5.0 Alpha does the job very well. It allows you to load source in text, HTML, Lit, PDF, PalmDoc (prd/prc), rb and few other formats and process them into native LRF format - plus few others I do not really care about. The result is nice, readable LRF file with three sizes, nicely formatted, with metada. As added benefit, because the author is Russian, the program does not assume that English alphabet is the only one in existence and allows to select encoding. The result is quite good - most of the extended characters from Czech/Slovak are there, some are missing and displayed as space (namely ř,ě,ľ ...) but it is readable. What is maybe better option is that with English as language and default encoding, the software \"downscales\" the extended characters to closest English pairs: ř -\u0026gt; r,ě -\u0026gt; e - which results in familiar computer Czech/Slovak. I am very comfortable with option 2, and will work on getting correct font for #1.\nIf you want to read more about the program go here and here - as long as you can read Russian. I found out that even after 22 years of not using Russian, I can still reasonably well read and understand it ...\nThe program is useful for creating Palmbooks as well as Microsoft Reader Lit book. I did not try that yet. User interface of Book Designer is not exactly Apple-made - extremely technical, geekish - looking like designed by engineer for engineers :-) - here is how it looks like. But it is the functionality that counts. Thank you - whoever made this possible :-).\nIf you want actually understand how the LRF format works and how the book is formatted on very low level, read the format spec and then download the BBeBinder from Google Code. It is C# 2.0 project, which aims to create something similar that BookDesigner - but as opensource, GPL-ed application. It is very early version (0.2) but in the true spirit of opensource, it actually (mostly) works. I have downloaded it and looked inside the code. The solution contains BBeB encoding/decoding library and main program, which was nicely designed with extensibility in mind. Using plugins, it allows to add additional input data formats (currently works well for text files, some HTML and I had mixed results with others).\nIf both of my projects were not in C# space (which is causing me being slightly over-see-sharped at the moment), I would not mind volunteering few hours into this - to make sure that Central European encoding is handled OK :-).\n","date":"March 22, 2007","externalUrl":null,"permalink":"/posts/2007-03-22-converting-ebooks-to-sony-reader-format/","section":"Posts","summary":"Since yesterday, I made nice progress in solving my issues with content creation for PRS500 and it's readability. There are several ways how to proceed:\nThe simplest is to download Book Designer. It is free for non-commercial use and current version 5.0 Alpha does the job very well. It allows you to load source in text, HTML, Lit, PDF, PalmDoc (prd/prc), rb and few other formats and process them into native LRF format - plus few others I do not really care about. The result is nice, readable LRF file with three sizes, nicely formatted, with metada. As added benefit, because the author is Russian, the program does not assume that English alphabet is the only one in existence and allows to select encoding. The result is quite good - most of the extended characters from Czech/Slovak are there, some are missing and displayed as space (namely ř,ě,ľ ...) but it is readable. What is maybe better option is that with English as language and default encoding, the software \"downscales\" the extended characters to closest English pairs: ř -\u003e r,ě -\u003e e - which results in familiar computer Czech/Slovak. I am very comfortable with option 2, and will work on getting correct font for #1.\n","title":"Converting eBooks to Sony Reader format","type":"post"},{"content":"After few weeks, I have got back to actually using my PRS500 again and I have finished the books loaded on the device. When I have connected the reader, first the CONNECT software as well as the PRS500 downloaded the updates. The firmware in reader is up to version 1.0.02.0130 from 1.0.00.21081 and should bring longer battery life and stability improvements. It better does, because so far the battery life is nowhere in the proclaimed range of 7000 page turns ... Time will show.\nThe desktop software update actually did improve user experience a lot - it went from \"terrible\" to \"almost acceptable\". New version added full screen preview mode and the interaction with CONNECT is much more pleasant - it does not freeze any more, contains \"Eject\" button to disconnect the Reader and (although it may be subjective feeling) the communication with the device is much faster. The program looks more and more like iTunes :-) - but I have no problem with that ...\nLast thing to do is to verify whether Sony did not install some rootkit, trojan or another pest on my machine. Since the last debacle with rootkit DRM I simply do not trust them any more. Good news is that the update did not require reboot, which lessens the likelyhood of a rootkit ...\nI have played a bit with formatting content for the reading. So far I am mostly using TXT books because there is no conversion required. To get best results try avoid hard line breaks - leave long lines - one line per paragraph and separate the paragraphs with empty line. TXT format can be presented in all 3 sizes and usually is quite acceptable. The problems of TXT based books is lack of ANY formatting (beyond paragraph), no metadata (author, year, tags), no images ... If your book is not in English, you may have problems with extended characters. So far I have not found good encoding that would present the extended Slovak/Czech characters correctly.\nTo get any kind of formatting, you need to use PDF, RTF or native LRF formats (the LRF format is also known as BBeB - broadband eBook). The PDF files needs to be specially formatted to be readable on Reader - ideally with the font size 12 to 20 and page size about 8.8 x 13 cm. More detailed instructions on PDF formatting from Sony are here. With PDF, device will allow only two font sizes. The Feedbooks web site offers some preformatted books for Reader.\nFor RTF, the size or the page does not matter so much, what is important is the font size. Best results are with 16 to 20 points and device alllows three sizes. The reformatting can be done in Word or OpenOffice. Unfortunately, same issue with extended characters is present in RTF rendering as well.\nTo get the best results, you need to convert eBook from TXT, PDF or RTF to LRF format. The LRF books can have metadata, table of content and nicer formatting with 3 sizes. I started to evaluate few tools to create the LRF content - will get back to it.\nFew more good resources on the Net: the discussion forum on MobileRead as well as Wiki. If you are into Shakespeare, here are his works in PRS500 format. ","date":"March 21, 2007","externalUrl":null,"permalink":"/posts/2007-03-21-sony-ebook-reader-software-updated/","section":"Posts","summary":"After few weeks, I have got back to actually using my PRS500 again and I have finished the books loaded on the device. When I have connected the reader, first the CONNECT software as well as the PRS500 downloaded the updates. The firmware in reader is up to version 1.0.02.0130 from 1.0.00.21081 and should bring longer battery life and stability improvements. It better does, because so far the battery life is nowhere in the proclaimed range of 7000 page turns ... Time will show.\n","title":"Sony eBook Reader - software updated","type":"post"},{"content":"Now this is something really interesting: as found on Adobe Labs site, their technology codenamed Apollo is approaching Alpha status. What Apollo is - in a nutshell - is another virtual machine, similar to Java runtime or .Net framework, with few minor twists: it is multiplatform (as Java) as well as multi-language (as .Net) at the same time. Before flame wars start - I am aware that JVM is capable (more or less) to support multiple languages beyond Java and also that .Net is (more or less) capable running on non-Windows platforms (e.g. Mono project), but that is not the point. The point is what is different about the Apollo compared to JVM or CLR.\nFirst thing that is different is developers skill-set. Adobe is trying to leverage the experience of Web application developers and allow to use traditionally Web oriented technologies to create desktop applications: HTML, Flash, Javascript and PDF in context of desktop applications. The other is that Apollo is designed with notion of being \"occasionally connected\", or in other words online/offline applications. It does support well the regime when you can work offline with local copy of the data and reconnect / synchronize with master copy on-line, providing both access to local resources (as traditional desktop application) as well as rich asynchronous XML capable communication library (as Web 2.0 application running in browser on the client).\nUsing Javascript/HTML for desktop-ish apps is not really an innovation. If you look on how the Firefox extensions are created, or on Widgets/Gadgets in Vista or OS-X you will see something very similar. The same idea was also implemented in Avalon - renamed to Windows Presentation Foundation - which uses XML to define the user interface and \"scripting\" that determines the logic. In WPF, you use the .Net languages to do \"scripting\" (Javascript being one of them) and you need a .Net 3.0 capable platform to run it (currently Windows XP SP2, Windows 2003 and Vista, unless I am mistaken). Even with similar language (Javascript), programming WPF is quite different and requires different skills from Web application programming. Allowing the use the Web app development skills and adding variety of Flash/Html/Javascript/Pdf combinations may be very appealing for somebody who needs to create desktop-like application without learning WPF. Plus the ability being platform-independent is added bonus and could be finaly a solution for a problem that Java did not really addressed well. It has been possible to create rich client Web-startable applications for several years and yet, it has not become the mainstream. Possibly because of the complexity of creating Swing-UI applications in a first place ?\nCompared to Firefox important point is that Apollo departs from browser while keeping the Web capabilities - such as rendering Web pages or creating mixed apps. Eliminating browser is important from security point of view. Installed runtime can give the Apollo application access to local machine resources such as local files without compromising security - as it would be in case of browser based applications. Access to local resources together with modern approach to remote connectivity is very interesting. The browsers are very much Web 1.0 with the request/response shaped vision of the world and adding the asynchronous capability in AJAX was one grandious hack ... Another good reason why getting rid of browser is simplicity of supporting one version of runtime versus making sure that you new great Web2 app works with wildly different Javascript/DOM capabilities of Internet Explorer 5, 6 and 7, Firefox 1.0, Safari, Opera, and so on ...\nThe demonstration videos on Lynda.com show few interesting capabilities of new application types - follow the 'Sample Apollo applications' link and also here.\nIt is still Alpha so it is too early to get excited, we have no data about performance, resource requirements or real world application development experience. Positive is that both runtime as well as SDK should be free. And it is always good to have more options available :-)\n","date":"March 20, 2007","externalUrl":null,"permalink":"/posts/2007-03-20-avalon-reloaded/","section":"Posts","summary":"Now this is something really interesting: as found on Adobe Labs site, their technology codenamed Apollo is approaching Alpha status. What Apollo is - in a nutshell - is another virtual machine, similar to Java runtime or .Net framework, with few minor twists: it is multiplatform (as Java) as well as multi-language (as .Net) at the same time. Before flame wars start - I am aware that JVM is capable (more or less) to support multiple languages beyond Java and also that .Net is (more or less) capable running on non-Windows platforms (e.g. Mono project), but that is not the point. The point is what is different about the Apollo compared to JVM or CLR.\n","title":"Avalon - reloaded ...","type":"post"},{"content":"Often, scientific \"failure\" teaches you more than success ... An experiment which gives you a clear answer is not a failure; it can surprise you, though. Failure comes only when an experiment answers no question -- usually because it's been done with ignorance or sloppiness. The true trick in science is to know what question your experiment is truly asking.\nGregory Benford\nTen Thousand Years of Solitude ","date":"March 19, 2007","externalUrl":null,"permalink":"/posts/2007-03-19-quote-of-the-day-5/","section":"Posts","summary":"Often, scientific \"failure\" teaches you more than success ... An experiment which gives you a clear answer is not a failure; it can surprise you, though. Failure comes only when an experiment answers no question -- usually because it's been done with ignorance or sloppiness. The true trick in science is to know what question your experiment is truly asking.\nGregory Benford\nTen Thousand Years of Solitude ","title":"Quote of the day","type":"post"},{"content":"Actually, maybe not really new, but I have noticed it just two days ago while trying to to clean up the clips collected from the Web.\nIt is sort of hidden feature, but very useful one: In Actions you can find 'Export in Google Docs \u0026amp; Spreadsheet'. It takes the current notebook and makes it a new document in you Google Docs. All texts, including pictures are transferred. It does very good job in keeping meaningful structure of the newly created document: every note will become an URL heading in document, pointing to the original.\nWhy I think this is so useful: with exporting doc, you get much better editing capabilities and also ability of collaboration (shared editing) with your friends. You will also get easy way how to transfer the notes into formats suitable for offline reading/backup: HTML/RTF/PDF/Word/Open Office.\nRead more here .\n","date":"March 18, 2007","externalUrl":null,"permalink":"/posts/2007-03-18-google-notebook-new-feature/","section":"Posts","summary":"Actually, maybe not really new, but I have noticed it just two days ago while trying to to clean up the clips collected from the Web.\nIt is sort of hidden feature, but very useful one: In Actions you can find 'Export in Google Docs \u0026 Spreadsheet'. It takes the current notebook and makes it a new document in you Google Docs. All texts, including pictures are transferred. It does very good job in keeping meaningful structure of the newly created document: every note will become an URL heading in document, pointing to the original.\n","title":"Google Notebook - new feature","type":"post"},{"content":"It happened few times in past few months: using Google to find out what is the time in Bombay or New Delhi, I used the search phrase \"India time zone\" and got two types of results. One was referring to the India Time zone as UTC+9hrs and the other was giving the correct answer - UTC+5:30. I know that whole India is in single time zone and this time zone is 5.5 hours before GMT. What did the UTC+9 mean ?\nAs I found out, the India in India time zone is not the India as a country, but military spelling of the time zone for letter I. The military uses letters to label time zone, starting with GMT or UTC being the Zero Meridian or Z time zone - spelled as Zulu time. Then going East, the zones go A, B, C - spelled as Alpha, Bravo, Charlie, Delta - up to the letter I which is spelled as India. West from Zulu you start with N, O, P - or November, Oscar, Papa ... Up to March 11 we were living in Romeo time zone, now we moved to Quebec time zone (again, nothing to do with La belle province, just spelling of Q)\nBtw, the military codes have their own \"loopback\" or \"localhost\" - the letter J refers to local time zone :-)\n","date":"March 14, 2007","externalUrl":null,"permalink":"/posts/2007-03-14-india-time-zone-mystery-solved/","section":"Posts","summary":"It happened few times in past few months: using Google to find out what is the time in Bombay or New Delhi, I used the search phrase \"India time zone\" and got two types of results. One was referring to the India Time zone as UTC+9hrs and the other was giving the correct answer - UTC+5:30. I know that whole India is in single time zone and this time zone is 5.5 hours before GMT. What did the UTC+9 mean ?\nAs I found out, the India in India time zone is not the India as a country, but military spelling of the time zone for letter I. The military uses letters to label time zone, starting with GMT or UTC being the Zero Meridian or Z time zone - spelled as Zulu time. Then going East, the zones go A, B, C - spelled as Alpha, Bravo, Charlie, Delta - up to the letter I which is spelled as India. West from Zulu you start with N, O, P - or November, Oscar, Papa ... Up to March 11 we were living in Romeo time zone, now we moved to Quebec time zone (again, nothing to do with La belle province, just spelling of Q)\n","title":"India Time Zone mystery solved","type":"post"},{"content":"Time to clean up the link cache again. I did not surfed much during last two weekends, so there is less to clean than usual :-).\nIf your computers are still confused about the DST change, here are some links that may be useful dealing with the issues - for Windows as well as for Mac. Speaking of which, I just checked that my Fedora Core 6 Linux-based NAS did recognized the DST without any issues at all as well.\nFor Gmail users with multiple accounts: check out this Firefox extension to displays email notifications. If you use Google calendar, there is another way how to synchronize with Outlook (should work with Outlook 2003 as well).\nThis site was recommended on Lifehacker to be a good resource for finding out whether the unknown process you have just seen in process list on Windows is a spyware or just some obscure undocumented system service: tasklist.org. Be aware, though - some of the advices may not be so great. For example, alg.exe is listed as trojan, however there is a system component with the same file name - Application Layer Gateway Service.\nThis website provides good introduction to Ruby. Ruby is interesting alternative to Python if you hate whitespace-is-significant type of formatting and still want the dynamic, functional programming language. Or if you want to find out what is the new Everything-On-Rails all about. If you are on the Mac, it is easy to try it out - open terminal window and type 'ruby -v' :-).\nIFTF blog - link collections focused on particular topic. Nice explanation how the Apple DRM works.\nFew noteworthy applications I have stumbled upon:\nPolyglot - tries to identify the (human) language based on fragment of text. Supports over 400 languages (Windows only). Google published version 5.0 of the Google Desktop. Looks very much like Vista. The PDFLab - nice free tool to split/merge the PDF files or to convert the sequence of JPG's to PDF (OS-X). iTunes 7.1 is out (for both Mac and Windows). Interesting file sharing application working as Firefox extension AllPeers went opensource.\n","date":"March 13, 2007","externalUrl":null,"permalink":"/posts/2007-03-13-webbits-2007-06/","section":"Posts","summary":"Time to clean up the link cache again. I did not surfed much during last two weekends, so there is less to clean than usual :-).\nIf your computers are still confused about the DST change, here are some links that may be useful dealing with the issues - for Windows as well as for Mac. Speaking of which, I just checked that my Fedora Core 6 Linux-based NAS did recognized the DST without any issues at all as well.\n","title":"Webbits 2007-06","type":"post"},{"content":"This year unusually early, we switched the Daylight Saving Time. The clocks did spring ahead one hour on Sunday morning. Btw, this is a good mnemonic how to remember which direction does the clock go: it Springs ahead and it Falls back ... Technically, it was decision of the US legislative to start DST early but because of the integration of the two economies, Canada had not much choice, just to follow. So, for next three weeks or so, we are one hour closer to Europe.\nAs a coincidence, we have been working with time and timezones related issues in both my C# related projects. Both project deal with data captured in different geographical locations and need to interpret the data timestamps from the point of view of user in particular timezone. In theory, .NET offers good support for time zones. In reality, the support is not really that great after all.\nWhat you can do very easily is to convert between local time of the Windows client and UTC. What you cannot do easily is to convert between any particular timezone and UTC - the conversion functions do not accept timezone code as parameter. What you also cannot do right out of the box is to provide user with list of all time zones and access the information like offset, date and time of DST etc (btw - both of these problems are much simpler in Java). Yes, it is not too hard to do it in C#, but every solution I have seen leads to one of two problems:\na) provides .NET wrapper using Windows timezone database in registry\nb) creates own timezone information (in database, XML file, Web service - you name it).\nNeither of these solution is really clean. Windows registry database is incomplete (contains only 75 zones) and it's accuracy depends on whether the Windows update is enabled or not (the Windows workstations installed in October without automatic update on did NOT recognize the early DST start this year). Accessing the registry may lead to priviledge problems and is generally problematic in Web applications. The information in the registry is pretty cryptic and the \"unique key\" is non-descriptive integer with no external world relation (the Index). If you can live with these limitations, look at this Codeproject article and on Michael Brumm's SimpleTimeZone class.\nIf you want to create and maintain own timezone database, you need first to get the authoritative source of the TZ data and then make sure you keep it up to date. If you use on-line source, you require permannent connectivity or some sort of synchronization - which adds amount of work required. Good starting point is this webpage.\n","date":"March 12, 2007","externalUrl":null,"permalink":"/posts/2007-03-12-times-are-a-changing/","section":"Posts","summary":"This year unusually early, we switched the Daylight Saving Time. The clocks did spring ahead one hour on Sunday morning. Btw, this is a good mnemonic how to remember which direction does the clock go: it Springs ahead and it Falls back ... Technically, it was decision of the US legislative to start DST early but because of the integration of the two economies, Canada had not much choice, just to follow. So, for next three weeks or so, we are one hour closer to Europe.\n","title":"Times are a-changing","type":"post"},{"content":"Same as last few weeks, I have spent most of the weekend reading. Unlike the weekends before, this time I was actually reading a book, not source code. It was nice change ...\nI have picked this small book with title Computers Ltd in Ottawa Public Library last Friday, while returning some books on CD. Written by David Harel of Weizmann Institute of Science, Rehovot, the book is trying to explain what computers cannot do. It speaks about complexity, P / NP problem and other fundamental limitations of what we can and cannot do with our favorite toys. This book is nice proof that even on such complex and abstract problems it is possible to find very nice and readable presentation - without sacrificing the precision. It reads as novel and thanks to very short format, it is an excellent complement to quiet Sunday afternoon. Recommended.\nAnd speaking of mathematics, here is a way how to tell extroverted mathematician from introverted mathematician (for all you folks interested in M-B classification and similar:\nThe difference between an introvert and extrovert mathematicians is:\nAn introvert mathematician looks at his shoes while talking to you. An extrovert mathematician looks at your shoes.\n","date":"March 11, 2007","externalUrl":null,"permalink":"/posts/2007-03-11-computers-ltd/","section":"Posts","summary":"Same as last few weeks, I have spent most of the weekend reading. Unlike the weekends before, this time I was actually reading a book, not source code. It was nice change ...\nI have picked this small book with title Computers Ltd in Ottawa Public Library last Friday, while returning some books on CD. Written by David Harel of Weizmann Institute of Science, Rehovot, the book is trying to explain what computers cannot do. It speaks about complexity, P / NP problem and other fundamental limitations of what we can and cannot do with our favorite toys. This book is nice proof that even on such complex and abstract problems it is possible to find very nice and readable presentation - without sacrificing the precision. It reads as novel and thanks to very short format, it is an excellent complement to quiet Sunday afternoon. Recommended.\n","title":"Computers Ltd.","type":"post"},{"content":"","date":"March 10, 2007","externalUrl":null,"permalink":"/tags/quote/","section":"Tags","summary":"","title":"Quote","type":"tags"},{"content":"Data is zeroes and ones — software is zeroes and ones and hard work.\nAs seen on The Third Bit.\n","date":"March 10, 2007","externalUrl":null,"permalink":"/posts/2007-03-10-quote-of-the-day-4/","section":"Posts","summary":"Data is zeroes and ones — software is zeroes and ones and hard work.\nAs seen on The Third Bit.\n","title":"Quote of the day","type":"post"},{"content":"The following may interest you only if you are using my favorite file manager (IMHO, it is the best file manager ever created, but your mileage may vary ..)\nList of selected files to Clipboard\nOne of the things that I am doing over and over is to search subtree - set of files for some content and then do something with the result. Let's say for example that I need all SQL files which refer to TESTDATABASE. On Unix, fastest way is to use find and pipe the result. On Windows, my workflow (using TotalCommander) is:\n- Alt-F7 (Commands -\u0026gt; Search)\n- enter *.sql in 'Search for, Alt-t + enter TESTDATABASE and hit Enter\nThe list of matching files is displayed, you can view content of file, go to file or (what I usually do) is Feed to Listbox. The listbox view is very useful - contains list of files from various subdirectories, you can either inspect the content (using F3), edit files (using F4), show it's location in other panel (Ctrl-arrow left/arrow right, depending on in which panel you are, use arrow for other panel).\nWhat I am usually interested in, is subset of files and I use Ins to select the files of interest. With selected set of files you can do what you need: copy them (F5), move them (F6), delete (F8) or ZIP them to archive (File-\u0026gt;Pack). So far so good.\nWhat I was not aware of is the you can very simply get the list of all selected files - with or without path - to clipboard. In fact, this works for any selected set of files, not only search results. In order to do this, you need to extend the menu (or add button, but menu works better for me).\nGo to directory where TotalCommader is installed (e.g. c:\\totalcmd), and edit the default menu file - c:\\totalcmd\\LANGUAGE\\WCMD_ENG.MNU. It is a text file with simple syntax. Add under Commands POPUP\nMENUITEM SEPARATOR\nMENUITEM \"Selected file to CLP\", cm_CopyNamesToClip\nMENUITEM \"Selected file to CLP with path\", cm_CopyFullNamesToClip\nLast thing to do is to make sure the TC uses the menu file. Go to Configuration -\u0026gt; Options, Language, select Main menu to be the file you have just edited and press Apply.\nAfter this, you will be able select any file, and using Command-\u0026gt;Select File to CLP, list will be copied to clipboard\nShow content of file without opening Viewer window\nJust press Ctrl-Q. To hide press Ctrl-Q again\nAdvanced select file\nIn addition to selecting file one-by-one (Ins), group (shift/click) you can use the Num-+, Num-- and Num-* to select, unselect or invert selection. The operations are cumulative, you can select all EXE files, the add all DLL files - or select all files and then unselect one or more group. This is pretty obvious and TC user know it well.\nWhat is less obvious is that you can use multiple patterns at the same time - e.g. \"*.EXE *.DLL\" will select/unselect BOTH EXE and DLL files.\nWhat I did not know - because I never read manual for new versions as they kept coming for the years I was using TotalCommander since 1992) - that you can use regular expression for search and selection dialog. The above multiple patterns is just a special case. The details are in Help-\u0026gt;Regular expressions, but one is so useful that I must mention it: select except: everything after '|' will get subtracted - \"*.EXE *.??L|*.WUL\" will select all EXE files and all files ending on L in extension, except .WUL. This may NOT be so useful in Select files dialog, but is very useful in Synchronize Dir - see next hack.\nSynchronize directories\nThe function allowing compare directories is something I use every day. Typical scenario is to find out out changes in two CVS sandboxes, containing different branches what was changed/removed added. It works great, with one minor issue - because of the different branches, the files within the CVS subdirectories will be different and will show in list of the changed files.\nUsing the following regular expression the File selection box (the middle combobox) will fix the problem:\n*.*|Entries.* Repository Root\nand make the CVS subdirectories disappear\n","date":"March 9, 2007","externalUrl":null,"permalink":"/posts/2007-03-09-useful-hacks-for-totalcommander/","section":"Posts","summary":"The following may interest you only if you are using my favorite file manager (IMHO, it is the best file manager ever created, but your mileage may vary ..)\nList of selected files to Clipboard\nOne of the things that I am doing over and over is to search subtree - set of files for some content and then do something with the result. Let's say for example that I need all SQL files which refer to TESTDATABASE. On Unix, fastest way is to use find and pipe the result. On Windows, my workflow (using TotalCommander) is:\n","title":"Useful hacks for TotalCommander","type":"post"},{"content":"My favorite top ten epigrams, for more see http://www.cs.yale.edu/quotes.html\n0. One man's constant is another man's variable\n1. It is easier to write an incorrect program than understand a correct one.\n2. If you have a procedure with ten parameters, you probably missed some.\n3. A language that doesn't affect the way you think about programming, is not worth knowing.\n4. Simplicity does not precede complexity, but follows it.\n5. You can't communicate complexity, only an awareness of it.\n6. Beware of the Turing tar-pit in which everything is possible but nothing of interest is easy.\n7. In a 5 year period we get one superb programming language. Only we can't control when the 5 year period will be.\n8. In computing, the mean time to failure keeps getting shorter.\n9. In programming, everything we do is a special case of something more general -- and often we know it too quickly.\nA. It is easier to change the specification to fit the program than vice versa.\nB. Systems have sub-systems and sub-systems have sub- systems and so on ad infinitum - which is why we’re always starting over.\nC. Everyone can be taught to sculpt: Michelangelo would have had to be taught not to. So it is with great programmers.\nD. To understand a program you must become both the machine and the program.\nE. Perhaps if we wrote programs from childhood on, as adults we’d be able to read them.\nF. One can only display complex information in the mind. Like seeing, movement or flow or alteration of view is more important than the static picture, no matter how lovely.\n","date":"March 7, 2007","externalUrl":null,"permalink":"/posts/2007-03-07-epigrams-on-programming/","section":"Posts","summary":"My favorite top ten epigrams, for more see http://www.cs.yale.edu/quotes.html\n0. One man's constant is another man's variable\n1. It is easier to write an incorrect program than understand a correct one.\n2. If you have a procedure with ten parameters, you probably missed some.\n3. A language that doesn't affect the way you think about programming, is not worth knowing.\n4. Simplicity does not precede complexity, but follows it.\n5. You can't communicate complexity, only an awareness of it.\n","title":"Epigrams on Programming","type":"post"},{"content":"I have just finished listening to the back-episodes of Security Now! # 38, where Steve Gibson describes his approach to securely browsing Web without antivirus and with Internet Explorer. The idea in a nutshell is - use properly locked down IE zones. Steve has modified the security settings of the default (Internet zone) to maximum: not allowing any scripting, cookies etc. Which makes many sites unusable, of course because increasing number of browsers does require Javascript enabled - or else game is over.\nFor the sites that do need the scripting, Steve recommends adding them to list of trusted site EXPLICITLY, one by one, site by site. This way, only the sites you use and are interested in will get any chance of running code within you browser.\nThis is very good idea, but has two weak points. First is that it is Internet Explorer and Windows only technique. True enough - combination of Windows users with IE defines the most virus/malware sensitive group of the Net population, but many exploits are impacting Firefox users as well and in Firefox, the zone technique does not work. The second problem is that your list of trusted sites is machine specific. If you are using multiple computers, you will have repeat the process of granting trust to your sites on each of them. I am afraid that few users will have the stamina of doing it ... Even with single computer, it requires patience of a saint.\nAs many times before: when there is a trade-off between security and convenience, guess what will win ?\n","date":"March 6, 2007","externalUrl":null,"permalink":"/posts/2007-03-06-security-of-the-browsers/","section":"Posts","summary":"I have just finished listening to the back-episodes of Security Now! # 38, where Steve Gibson describes his approach to securely browsing Web without antivirus and with Internet Explorer. The idea in a nutshell is - use properly locked down IE zones. Steve has modified the security settings of the default (Internet zone) to maximum: not allowing any scripting, cookies etc. Which makes many sites unusable, of course because increasing number of browsers does require Javascript enabled - or else game is over.\n","title":"Security of the browsers","type":"post"},{"content":"It has been half a year in March since we have started to use Wiki as main project management, collaboration and content creation tool. I think this is period long enough to look back and summarize what we have discovered, what worked and what not. This was not the first attempt to use Wiki in this context - however, it was first case when the result can be considered full success. I have tried (both in at-home and project environments) several Wiki implementations, notably JSPWiki,MoinMoin, FlexWiki, Wiki module for DotNetNuke and MediaWiki over period of about 5 years. During this process I have discovered by trial and error, which features are important in software development project environment and what are the conditions/consequences of using Wiki as main information hub.\nWiki selection\nThe Wiki engine we have selected for the biometric project was commercial Java-based implementation from Atlassian software Confluence. The main selection criteria was platform independence (we wanted OS-independent solution that could talk to variety of databases), technology alignment (to use in-house expertise), enterprise-readiness (possibility to integrate with other systems - issue tracker, security, ease of administration) and high user comfort ( easy of use for technical users, advanced features for developers).\nWiki and content creation\nFor software development, the content of the Wiki is not your main deliverable - it is the source code. Neither is Wiki the tool that is used to create or manage the main deliverable (source code) - this is the responsibility of source code management system. The content you can put into Wiki is mostly targeting the phases BEFORE coding and AFTER coding, and auxiliary information about coding during actual implementation.\nIn the \"Before Coding Phase\" we have used Wiki as main hub for both requirements, analysis and use cases. It was harder than it sounds because - let's face it - the user comfort of the Web based WYSIWYG editor is not quite in the same league as the Word or even OpenOffice Writer. The more Office addicts and Word power users you have in team, the longer it takes some time to adjust.\nThe main advantages we have seen from going with Wiki was immediate visibility of the documents and no version control issues. No time was spent on emailing DOC files around, looking for latest and greatest specification version, or spending time integrate the comments from review. The analysts were able to work on live document, with full history of changes available any time (attributed to authors). When reaching the milestone, they could with one click generate the PDF snapshot, archive it or put it to document management system and move ahead. The full text searchability of the content has proven to be an important time saving feature - to achieve the same flexibility with Office documents you need to use something like Google Desktop or run OS-X or Vista.\nEspecially in the early stages of content creation, we appreciated a lot extremely dynamic cross-linking capabilities of Wiki. If you have ever tried to maintain Word document with many cross references and internal links, you may have an idea why :-). It was much easier to create chunks of content first and worry about structure later. Confluence puts pages into tree structure, which can be used to organize your content into logical, coherent units. It also provides very easy way how to rearrange page position the the tree, including subpages. What was very useful, were actually page comments - if you were not sure about changes, you could add comment that was carried around with the page, eventually incorporated into page content. Another very good feature we have used was tagging: it allows to create multiple additional structure, completely independent from page tree, with single page having many tags and \"appearing\" in multiple places in the structure.\nDuring actual coding, we have used Wiki document everything that was related to project builds, configuration, test data, database loading procedure, as well as the base for creating the test cases.\nIn the \"After Coding Phase\", Wiki is the ideal place where you can put information about releases, installed builds. Confluence integrates very well with other Atlassian product - JIRA Issue Tracker - and using both, we could easily use Confluence pages as details for the bugs and issues in JIRA as well as the other way - refer to JIRA or even document current list open issues in the particular project release. Wiki was the place where the README.txt nad \"Installation Guide\" were created - way before they actually needed.\nWe have had several discussions on how far can Wiki replace the document management system and came to the conclusion that it can - in limited way. What is Wiki perfect for is the content creation and collaboration on \"living\" content. Because any page can have zero to many attachments (binary or PDF) you can, technically, use it as repository for released versions of the document (e.g. set of pages rendered as PDF or even copied into Word document if you must). There are many way how to implement it - either by creating separate workspace, or using tag RELEASED or simply by page naming convention. This is however not solution with the same strength as dedicated document management system - it is lightweight, uses semi-automated workflows and requires some discipline. It really depends on your particular business case (number of users, documents, business processes) whether you want to use it or go after some bigger (and often much more expensive) solution.\nWiki and project management\nRight after ubiquitous Microsoft Project, Wiki can easily be the most useful tool for project manager.Wiki will never replace MS Project, but it complements it in many ways. It can contain both information that is either too high level to be managed in Project, or too detailed (like detailed work breakdown). It can be also used as communication tool by providing the PDFor JPG renederings of current project plan to the team and/or customer - as not everybody has installed MS Project.\nIn about middle of the project Peter defined \"project blog\" - subtree of pages, indexed by the weeks, where team members documented changes, news or suggestions for the others. Unlike emails, the information was available from any place, fully searchable and could refer/be referred from other Wiki pages. Speaking of email, Confluence has great feature that we have not really utilized: you can use it email repository and make the email search-able, visible - turn it to discussion forum or knowledge based. In every project, email is hidden reservoir of know-how which often goes uncaptured ...\nCost of using Wiki\nNo, I do NOT mean the amount of money you have to pay for your software license. Even if it not negligible, we all know that the true cost of every software is mostly in human labor needed to keep it alive and well. As the person being responsible for installing, administering and managing data for Wiki, I am happy to report that this cost is actually very affordable.\nAfter initial install which takes (depending on database selected and amount of integration points and your familiarity with Tomcat and web application configuration) between 20 minutes and 2-3 hours, I had only one case when some maintenance was required: to increase amount of memory available for the JVM. The rest was done automatically. Confluence does every day automated backup which put the actual pages (as XML export format) plus attachments into ZIP file - all you have to do is to include the backup directory to your system backup, or make sure it sits on some secure RAID-5 or mirrored disk device. Being slightly paranoid when it comes to backups, I have chosen both, and in addition I have also scheduled automated DB backup to save the page content in binary format as well.\nWiki and mobile workers\nIn order to use Wiki, you need to have connectivity - to Internet in general, and specially inside the network where your Wiki installation lives. Which may not be always available. With Confluence, we found out that you can have at least read only access to all the knowledge contained in the Wiki. The key is export functionality. Workspace can be exported either as PDF or as HTML tree (including the attachments). Both can be viewed online (with limited search functionality). This is very feasible solution for e.g. offsite support where connectivity to source Wiki is not available.\nCriteria for success\nSo what makes Confluence special that using it succeeded where other Wiki's did not ? Few things, IMHO. First of all, is easy of use and generally very polished user experience. When you are editing content, the UI you have is very good for Web application. It does save your changes, does not loose your content. You can switch between \"markup\" and WYSIWYG. With single click, you can convert the page to PDF. Very easy way how to create tables. The copy of the text from Word or browser actually can be posted into Wiki editor and keeps formatting. Linking pages is very efficient. Inserting images (including thumbnails) is extremely comfortable. It provides very powerful macros - such as picture gallery, or list of all child pages.\nSecond are the enterprise-readiness features such as security. Plug-gable authentication. Automated backups. Good administrative interface. Extensibility through plugins. Open architecture and availability of the source code (no vendor lockup). Ease of install and very low maintenance. Open data interchange format (XML). Very easy way how to track changes and \"one click undo\" should the information be deleted or damaged.\nThe third factor is related to calendar year and shift in perceiving. Unlike in 2002-2003, Wiki's are mainstream and everybody is aware of their existence and their value (see Wikipedia for the most visible example). General shift towards using more on-line application and less dependence on locally installed software (thanks to Google and others). User's experience improvement thanks to Web 2.0/AJAX features. Much less discomfort of working with data that \"out there\", not on your local machine.\n","date":"March 5, 2007","externalUrl":null,"permalink":"/posts/2007-03-05-project-management-using-wiki/","section":"Posts","summary":"It has been half a year in March since we have started to use Wiki as main project management, collaboration and content creation tool. I think this is period long enough to look back and summarize what we have discovered, what worked and what not. This was not the first attempt to use Wiki in this context - however, it was first case when the result can be considered full success. I have tried (both in at-home and project environments) several Wiki implementations, notably JSPWiki,MoinMoin, FlexWiki, Wiki module for DotNetNuke and MediaWiki over period of about 5 years. During this process I have discovered by trial and error, which features are important in software development project environment and what are the conditions/consequences of using Wiki as main information hub.\n","title":"Project management using Wiki","type":"post"},{"content":"Thanks to exploring the Google calendar (when playing with public calendars related to Ottawa) I found the Ottawa Mac User group's calendar and discovered that\na) they exist\nb) they hold monthly meetings in nice Irish pub at the Market The group is actually named Bytown Mac User's group, for the reasons explained on the Web site or here.\nSo I decided to go there. I thought - what the heck, worst thing that can happen that I will have a glass of Guinness at the pub I never visited before, which is not a bad thing at all. And besides, the Rideau Chapters store is very close (the plan B). It turned out pretty well, though - meeting was interesting. The group is fairly small (I believe somewhere about 10-15 people) but nice, friendly, dedicated and interesting. It sort of reflects the Mac representation in the market. Unlike when attending Microsoft users events, where almost everybody is by profession tied to the software development of IT business, here larger percentage of people did something non-primarily computer related for living - like creative writing, art, video processing. Again - it represents well the real world situation. Not too many people that actually do software development (other than Web design) but there was one guy who is exploring the same path as I am looking for: Objective C and Cocoa development.\nThe presentation was focused on MAc based backups and was very informal, kind of cross between group discussion and presentation. No slides, just demo and talk, short and sweet. I have learned a cool feature that I was not aware of before: zooming feature of the OS-X. Just try - from any application - holding down Ctrl key and double-finger scroll, and see for yourself. This is so amazingly practical for the demo's and presentation - no font size changes, just zoom in/zoom out. Cool.\nI will be back next month :-). Gabo/Milos - interested to join me ?\n","date":"March 4, 2007","externalUrl":null,"permalink":"/posts/2007-03-04-ottawa-mac-users-group-meeting/","section":"Posts","summary":"Thanks to exploring the Google calendar (when playing with public calendars related to Ottawa) I found the Ottawa Mac User group's calendar and discovered that\na) they exist\nb) they hold monthly meetings in nice Irish pub at the Market The group is actually named Bytown Mac User's group, for the reasons explained on the Web site or here.\nSo I decided to go there. I thought - what the heck, worst thing that can happen that I will have a glass of Guinness at the pub I never visited before, which is not a bad thing at all. And besides, the Rideau Chapters store is very close (the plan B). It turned out pretty well, though - meeting was interesting. The group is fairly small (I believe somewhere about 10-15 people) but nice, friendly, dedicated and interesting. It sort of reflects the Mac representation in the market. Unlike when attending Microsoft users events, where almost everybody is by profession tied to the software development of IT business, here larger percentage of people did something non-primarily computer related for living - like creative writing, art, video processing. Again - it represents well the real world situation. Not too many people that actually do software development (other than Web design) but there was one guy who is exploring the same path as I am looking for: Objective C and Cocoa development.\n","title":"Ottawa Mac User's group meeting","type":"post"},{"content":"Gabo sent me this link - it is some half-joke half serious knock-off of the Myers-Briggs personality classification. Same as in case of MB, it gives you four letters. Unlike in MB, the letters are different:\nInstead of E/I - Extroversion or Introversion, N/S (iNtuitive / Sensing), T/F (Thinking/Feeling) and J/P (Judging/Perceiving),\nit classifies you either as D/P - Doer or Planner, L/H - Low or High level programmer, S/T - Solo or Team programmer and C/B Conservative/liBeral.\nQuick characteristics of the groups:\nDoer (very quick at getting tasks done, focusing on outcome You believe the outcome is the most important part of a task and the faster you can reach that outcome the better. After all, time is money.\nPlanner (slower, but you'll usually find the best solutions)\nLow level (old school of programming preferring the intimate relationship with the computer and coding to bare metal)\nHigh level (seeing the objects and components)\nSolo situation (The best way to program is by yourself)\nTeam (believing that group is better than the sum of it's parts)\nConservative programmer. (write short and to the point code that gets the job done efficiently.\nliBeral programmer (as we are not writing on paper anymore so we can take up as much room as we need).\nNow this is of course not meant as anything as serious as MB, but there are still interesting parallels: the Solo/Team preference corresponds to I/E type - introverts would prefer to program alone, extroverts in team. The L/H has in my opinion some relation with S/N - as the higher degree of detail and \"down to metal\" focus mash better with sensing approach, whereas more abstract concepts like objects and components seems to be closer to conceptual, large picture intuition. The D/P seems to be related to P/J: judging types will IMHO be more likely to plan and evaluate alternatives, whereas the doers will not mind react to the change as it occurs - the P treat.\nWhat do you think ? (I really wish Connie could do this test - too bad it is heavily profession biased).\nTake 10 minutes and see for yourself.\n","date":"March 3, 2007","externalUrl":null,"permalink":"/posts/2007-03-03-programmers-classification/","section":"Posts","summary":"Gabo sent me this link - it is some half-joke half serious knock-off of the Myers-Briggs personality classification. Same as in case of MB, it gives you four letters. Unlike in MB, the letters are different:\nInstead of E/I - Extroversion or Introversion, N/S (iNtuitive / Sensing), T/F (Thinking/Feeling) and J/P (Judging/Perceiving),\nit classifies you either as D/P - Doer or Planner, L/H - Low or High level programmer, S/T - Solo or Team programmer and C/B Conservative/liBeral.\n","title":"Programmer's classification","type":"post"},{"content":"Disclaimer first: I really like GMail. Since I started using it (about year ago), I learned to appreciate the beautiful simplicity and elegance of the Web interface. And since I switched completely to GMail as foundation of all my email systems (about November 2006), I have managed to simplify most of my email related chores. But let's face it - GMail is far from perfect. Here is list of the annoyances and missing features that I have collected:\nPOP access.\nIt is there. It is free. It works. (Hey, Yahoo! - paying attention: available and free). So what is the catch ? It is single client POP solution only. As soon you download the email with ANY POP client, neither of other clients will see this email message as new and download it. This solution works for those who (as myself) use Web interface only and have single, permanently running POP email client (e.g. Thunderbird) just to keep backup copy of all email. For this purpose, it works perfectly - and you will appreciate that GMail will send to POP client even the Sent emails, not only received. If you are, on the other hand, using simultaneously a notebook with Outlook, desktop with another POP client AND Smartphone and would like to have all your emails downloaded on all of them all the time, you are out of luck.\nEven with the first \"backup only\" scenario, I do run into troubles from time to time: if my \"backup client\" on desktop stops working (either machine is down or the Thunderbird hangs) , and I start Mail.app on the Macbook - \"wroooom\" - it downloads all new emails without merc, which means they will never be included as part of my backup (unless you manually transfer them, which is major P.I.T.A)\nLast issue with POP access is tagging within downloaded emails: none. Regardless how much time you have spent properly labeling your emails, none of it will ever make it to POP client. Labels are Web Only\nWhat would be the fix ? For downloading, the right approach would be clearly - let POP client decide which emails are \"new\" in its context. It certainly can be done, because this is the mode in which Rogers-Yahoo! operates. I am not sure whether there is simple solution for the labels download - the problem with labelled email is that most client support only folders and emails can be multi-labelled, which makes it position in folder hierarchy problematic.\nSorting\nAccording the official mantra, search is better than sort. It may be true, most of the time. I have been often in situation, where I would prefer the sorting. For example by name or by date sent. Or even subject. One feature that I always liked about Outlook was the default \"grouping\" of emails by time: Today, Yesterday, Week Ago etc. Occasionally, it is also useful to sort by attachment size.\nContact Management\nThis is, IMHO the weakest point of GMail. The contacts management's UI is far from good. It takes too many clicks to do changes and some simple things are just too frigging hard/impossible: try for example \"merge\" several email addresses you have collected for the same person, or edit multiple records. I was thinking about using external application to maintain contact list, but GMail does not really synchronize with anything - all you can do is export and import CSV files. The solution would be very simple: just provide the public API for the address book - and the community will take care of the rest.\nLabeling\nThis very strong, unique feature of GMail works very well, but I see several areas where it could be improved:\nallow time sensitive labels - e.g. \"last 3 days\" label, that would display different content based on expression allow hierarchical labels e.g. work-\u0026gt;project1, work-\u0026gt;project2 - everything labelled by either project1 or project2 would automatically have the label work as well allow visual attributes to labels - similar as colors in Finder. If label has assigned color, use it as background in email list allow drag and drop of selected messages to labels offer tag-cloud as alternative rendering to linear list ","date":"March 2, 2007","externalUrl":null,"permalink":"/posts/2007-03-02-what-is-wrong-with-gmail/","section":"Posts","summary":"Disclaimer first: I really like GMail. Since I started using it (about year ago), I learned to appreciate the beautiful simplicity and elegance of the Web interface. And since I switched completely to GMail as foundation of all my email systems (about November 2006), I have managed to simplify most of my email related chores. But let's face it - GMail is far from perfect. Here is list of the annoyances and missing features that I have collected:\n","title":"What is wrong with GMail","type":"post"},{"content":"The Ottawa .NET Community organized today interesting lunch-and-learn session: first of two sessions on introducing the Rocky Lhotka's CSLA Framework. Usual location - Glacier Room at downtown Microsoft Office. I decided to attend for two reasons: first was that I knew the presenter - David Campbell. David is a great guy - consultant with 20 years of history in the software development business, running his own company. Last year when we were looking for people with CSLA experience in Ottawa, David's name came out first.\nMy second reason was a educational. No, I did not really expect to learn something new about CSLA. We are using the framework on two projects since summer 2006, I have read the book (and agree with David that it is good but a pretty dry read) and also read and wrote quite some amount of code that uses the framework. I certainly do not think that I know enough about CSLA (as the German proverb says, man lernt nie aus ) but it is hard to go during introductory session to the level of detail that uncovers anything new to active users of the CSLA. What I was looking for is an inspiration how to present the framework to the developers who are new to it - and I was not disappointed. And btw, I *did* learn something completely new about CSLA: that SmartDate trick with \".\", \"+\" and \"-\" is really neat (see the source code of SmartDate unit tests).\nWhat I always enjoy on the ODNC sessions is discussion during and after the presentation. It was like this last time (Adam Machanic) and it was like that today. People ask great questions (OK - with one expection - if you are ODNC regular, you know who I am talking about).\nWe have had lots of discussion in-house about the relative pros and cons of using CSLA. In our projects, portions of the CSLA functionality are not so important: we do not really need multi-level undo, for one example. On the other hand, the location-independent business objects and scalability it gives you is really nice. Yes - CSLA forces you to do things certain way, which may not be considered ideal, but at least it results in consistent approach across the codebase.\nCSLA has pretty steep learning curve, even with the books available and the way of doing things can look strange to seasoned object oriented designer. Heavy use of generics and design of the core framework classes forces you to use very flat object hierarchies. Instead of inheritance, it pushes either towards sharing functionality with wrapping or using code generation. I am not exactly crazy about the read-only/readwrite object dichotomy - without use of inheritance, it often leads to code duplication.\nAlso the book example on Projects and Resource is IMHO not the most illustrative one: it puts too much emphasis on dealing with lists of objects and does not illustrate many important aspects of dealing with root objects and switchable (root/child) objects. I had trouble of using this example for in-house training and mentoring: it is not simple enough to make obvious things really obvious and not comprehensive enough to cover many everyday situations.\nDespite of all that, our experience with CSLA was overly positive: we were very pleased with performance compared to plain datasets and after few initial hick-ups, the framework allows you to create very solid, reusable, scalable layer of mobile business objects.\nDavid is going to do Part Deux of the CSLA intro, which should be practical exercise of creating address book applicatopn based on CSLA with multiple UI. Looking forward to it - maybe that example will fill the gap ...\nAnd btw - thanks, David.\n","date":"February 28, 2007","externalUrl":null,"permalink":"/posts/2007-02-28-introduction-to-csla-lunch-presentation-at-odnc/","section":"Posts","summary":"The Ottawa .NET Community organized today interesting lunch-and-learn session: first of two sessions on introducing the Rocky Lhotka's CSLA Framework. Usual location - Glacier Room at downtown Microsoft Office. I decided to attend for two reasons: first was that I knew the presenter - David Campbell. David is a great guy - consultant with 20 years of history in the software development business, running his own company. Last year when we were looking for people with CSLA experience in Ottawa, David's name came out first.\n","title":"Introduction to CSLA - lunch presentation at ODNC","type":"post"},{"content":"It is not Friday today and I am obviously late with next link collection. Somehow I have completely missed the weekend - so much was happening at work that I had barely had time to notice what is going on on the Web. My Google Reader is overflowing with new links and there are lots of new links in delicious. Let's start.\nMerlin Mann of 43folders started to do videopodcasts - have a look (in the second edition he interviews Jonathan Coulton, famous creator of the Code Monkey song). This little utility allows to synchronize contacts and tasts between Thunderbird and PocketPC. Interesting article on how to make Gmail you personal information centre.\nGood article on the Zen-like \"productivity zone\" state and how to reach it. Tutorial how to sync address book via IMAP. The.NET addict published two more articles in the series of \"Windows developer learning OS-X programming: this time he compares NIB and XAML and the Objective-C 2.0 categories with C# 3 LINQ extensions. Hmmm !\nSome new software: for Windows, Virtual PC 2007 is out. ASP.NET developers - this Viewstate viewer is really useful. Version 5.0.3 of fantastic Reflector is available. For Web workers - top web tools for college students - but you will them useful even if you are not one. For Mac users - automate the network share mounting based on your location and tagging add-on for iTunes.\nInteresting series of articles on software maintenance. Guide how to switch from Windows to Linux (from IBM). Registers suggests that if you are buying new laptop, go for Mac (Milos/Gabo - they say almost exactly what were talking about today ...). With few exceptions, if you want to avoid Vista, Mac + XP in Parallels is your best choice as most manufacturers are offering only Vista notebooks.\n","date":"February 27, 2007","externalUrl":null,"permalink":"/posts/2007-02-27-webbits-2007-05/","section":"Posts","summary":"It is not Friday today and I am obviously late with next link collection. Somehow I have completely missed the weekend - so much was happening at work that I had barely had time to notice what is going on on the Web. My Google Reader is overflowing with new links and there are lots of new links in delicious. Let's start.\nMerlin Mann of 43folders started to do videopodcasts - have a look (in the second edition he interviews Jonathan Coulton, famous creator of the Code Monkey song). This little utility allows to synchronize contacts and tasts between Thunderbird and PocketPC. Interesting article on how to make Gmail you personal information centre.\n","title":"Webbits 2007-05","type":"post"},{"content":"Most programmers love GUI. It is so easy, so convenient, just point and click here, click there, drag and drop, repeat few times and problem solved. Who in sanemind would bother typing and writing code when can GUI do it all. The convenience rules. If you need to add or change something, it takes just few more clicks. Not a big deal, just add a few more easy steps. No problem - right ? Wrong !\nWhat is wrong with this approach is that with few clicks after few clicks, the whole process becomes more and more complicated. It may need to be done differently, based on conditions. It may get different results if the order of clicking changes. If it needs to be done on more than single system, it start to be more like chore, than a shortcut. Something that needs to be done over and over is always very sensitive to human errors. And because the clicks do not leave audit trail, only the guy with the mouse in hand actually has any knowledge on what is going on. It is also very hard to keep the sequence of mouse clicks in CVS :-). And it is close to impossible to tell what was the difference between two series of clicks after they are done - one of which worked and one not.\nTo get repeatability, you need a process that starts and runs unattended, based on input parameters performs the task at hand. It can be either compiled program or script - but script is faster to create and easier to maintain. Therefore \"scripting\". The script allows to be version controlled, contains explicit decisions and it is the minimal documentation of the task. Without script that starts from well-defined state at the beginning and properly handles all tasks / transformations, you will never know in which state you have ended.\nNot all script were created equal. Many GUI tools allow you to perform tasks required and then generate scripts that (in theory) perform the same thing. This sounds like an ideal combination of both: you can keep using the GUI and by generating scripts, you keep trail of the changes for version control. Right ? Not quite, unfortunately.\nThe problem with generated scripts is, well, that they are generated and not written. They contain lots of repetitive information, many function arguments that are not really relevant to the task and no parameters. They are bad documentation because of the verbosity and can lead to problems with version control - small change in GUI setting may lead to very different script rendering.\nGenerated scripts *can* be used as started point to accelerate the initial steps, though. It is time consuming to start with empty file - but it is very often very educational and sobering experience. Generate first version of the script by tool, then developer takes over, changes the script structure, extracts parameters, re-factors repetitive steps to functions/procedures, adds comments. After this, the GUI should not be used as primary tool again, from that point on running the script should be the only way how to perform the task. If change is needed, edit the script and re-run it. This type of script is actually very useful: it is both documentation as well as tool, it can grow, evolve as the problem evolves and helps understand what is being done.\nTypical area where this is extremely visible is database development. In Microsoft world, the Management Studio (former QA) is tool that allows do most of the configuration tasks via GUI. If also will generate the SQL for the task - but the SQL will not be as flexible as it should be: it may contain hardcoded references to database, it may not be complete (e.g. script will generate ALTER PROCEDURE which will fail if procedure does not exist, rather than test existence and drop if exist, then re-create). Formatting will depend on settings - e.g. you may or may not get the brackets around identifiers - which will make version control of such script an interesting exercise.\nThe GUI tools can be great help if they are used by skilled person who understand their power as well as their limitation and use the GUI to speed up development, but does not depend/rely on the GUI tool exclusively. It usually takes some experience to realize the GUI trap and develop skills/habits outside of the GUI tool. Therefore when looking for e.g. senior database developer, try to test him/her with simple repeatable task that requires working without or outside of the GUI. If he/she has problems writing scripts by hand, using command line tools and scripting in general, it is not a senior developer, regardless how many years of experience has on the resume.\n","date":"February 26, 2007","externalUrl":null,"permalink":"/posts/2007-02-26-scripting-repeatability-and-gui/","section":"Posts","summary":"Most programmers love GUI. It is so easy, so convenient, just point and click here, click there, drag and drop, repeat few times and problem solved. Who in sanemind would bother typing and writing code when can GUI do it all. The convenience rules. If you need to add or change something, it takes just few more clicks. Not a big deal, just add a few more easy steps. No problem - right ? Wrong !\n","title":"Scripting, repeatability and GUI","type":"post"},{"content":"I have picked it two days ago in Chapters - Code Craft by Pete Goodliffe. Somehow similar in topics covered as the Rapid Development or From Coder to Developer - but newer. Divided into 6 parts:\nPart I - At the codeface - defensive programming techniques, naming, formatting, commenting, error handling\nPart II - The secret life of code - code contruction tools, testing and debugging methods, building\nPart III - The Shape of the code - code design, architecture, source code growth and decay over time\nPart IV - The Herd of Programmers - development practices and programming skills, psychological aspects of programming, communication\nPart V - Part of the Process - rites and rituals of software development, specifications, estimation, code reviews,\nPart VI - View from the top - high level view, sofware development metodologies.\nI started to read in rather unstructured way in chapter 16 (Code Monkeys) dealing with typology of programmers and chapter 17, covering the team and communication issues. I liked it a lot. Easy read, funny, entertaining and very practical. Often just common sense, but already formulated and properly packaged, ready to be communicated.\nI have decided to read the full book. Will post a review after I am done.\n","date":"February 25, 2007","externalUrl":null,"permalink":"/posts/2007-02-25-good-book-on-coding-and-software-development/","section":"Posts","summary":"I have picked it two days ago in Chapters - Code Craft by Pete Goodliffe. Somehow similar in topics covered as the Rapid Development or From Coder to Developer - but newer. Divided into 6 parts:\nPart I - At the codeface - defensive programming techniques, naming, formatting, commenting, error handling\nPart II - The secret life of code - code contruction tools, testing and debugging methods, building\nPart III - The Shape of the code - code design, architecture, source code growth and decay over time\n","title":"Good book on coding and software development","type":"post"},{"content":"It has been said that the great scientific disciplines are examples of giants standing on the shoulders of other giants. It has also been said that the software industry is an example of midgets standing on the toes of other midgets. [Alan Cooper]\nAnd the users exclaimed with a laugh and a taunt: \"It's just what we asked for but not what we want.\"\nFor a sucessful technology, honesty must take precedence over public relations for nature cannot be fooled. [Richard Feynman]\nThere's no sense being exact about something if you don't even know what you're talking about.[John von Neumann]\nYou cannot bullshit a compiler. [Anon]\n... the cost of adding a feature isn't just the time it takes to code it. The cost also includes the addition of an obstacle to future expansion. ... The trick is to pick the features that don't fight each other.[John Carmack]\nLearning is not compulsory. Neither is survival.[W. Edwards Deming]\nYou can't communicate complexity, only an awareness of it. [Alan J Perlis]\nIf you don't think carefully, you might think that programming is just typing statements in a programming language. [Ward Cunningham]\n\"If we wish to count lines of code, we should not regard them as lines produced but as lines spent.\"\n","date":"February 24, 2007","externalUrl":null,"permalink":"/posts/2007-02-24-more-great-programming-quotes/","section":"Posts","summary":"It has been said that the great scientific disciplines are examples of giants standing on the shoulders of other giants. It has also been said that the software industry is an example of midgets standing on the toes of other midgets. [Alan Cooper]\nAnd the users exclaimed with a laugh and a taunt: \"It's just what we asked for but not what we want.\"\nFor a sucessful technology, honesty must take precedence over public relations for nature cannot be fooled. [Richard Feynman]\n","title":"More great programming quotes","type":"post"},{"content":"We build software line by line, idea by idea, side by side. Our software is an expression of ourselves, our best moments, our toughest challenges, our greatest hopes.\nThis wonderful quote is from handcrafted copy of Vista, which was distributed to everybody who worked on a product. It is a Microsoft tradition that the people who worked on a project get a copy of the project when it ships.\nWhat a wonderful idea.\nRead more on Larry Osterman's blog.\n","date":"February 22, 2007","externalUrl":null,"permalink":"/posts/2007-02-22-really-nice-idea/","section":"Posts","summary":"We build software line by line, idea by idea, side by side. Our software is an expression of ourselves, our best moments, our toughest challenges, our greatest hopes.\nThis wonderful quote is from handcrafted copy of Vista, which was distributed to everybody who worked on a product. It is a Microsoft tradition that the people who worked on a project get a copy of the project when it ships.\n","title":"Quote of the day","type":"post"},{"content":"Back in old country, I once had a programmer working for me who made himself famous with the following quote:\n\"I have fixed that bug, do you want me to compile it too ?\".\nIn his mind, he was done as soon as he identified the bug and put the fix in the code. All the rest was trivial and unimportant routine.\nDuring last 20 years I have worked with many very different developers and learned the hard way, how very many different meanings the word \"done\" can have. For some, done means that coding just finished and he/she successfully compiled the projects and stepped through some of the code paths with debugger with negligible occurrences of major crash. Whether the code is in CVS, commented - who cares ?\nFor others it meant that unit test was written and run, code is commented and documented, everything is properly tagged and version-ed in source control system, built and deployed via automated build system (now do NOT laugh, the later are not mythical creatures, I really met few guys like that). The problem is that it takes some time while you find out who is where on the done-ness scale and making sure that the whole team is on the same degree of \"done-ness\" or at least in agreement what done means, can present quite some challenge and consume considerable amount of time from the project manager and/or team lead.\nWhat is your degree of done is a great question to ask when you are building new team and hiring developers. We had interesting discussion with Connie on the topic of hiring criteria and both came to a conclusion that biggest mistake you can make is to put too much weight on best technical skill-set match. The longer is the project, the less emphasis should be placed on skillset match - simply because skills will evolve but non-technical personality treats do not change - and in the long run, these may cause most troubles. For smart person, with good education and wide enough experience it is much easier to fully master some special area of expertise, especially when there is some time available. On the other hand, things like teamwork, work ethic, social skills, communication or \"degree of done\" are very hard to get and even harder to fix/develop.\nThe other reason why hiring only by skill match can be tricky is: how do you evaluate a supposed expert's expertise ? If do not have another expert (ideally better one), how do you validate how much of claimed experience is truly there and how much is just a nice wrapping, an empty shell lacking depth ? The risk in hiring somebody with boasted experience but lack of depth is that this person will inevitably become the key design/implementation influencer and decision maker in the given area of expertise. Eventually, as the project moves ahead, other team members will catch up and understand more and will question some of expert decision made - and the fun begins.\nAnother important \"must have\" for a good hire is multicultural background. No, I do not mean *that* type of multiculturalism as the politicians like to use: I mean the information technology cultures such as platforms, operating systems, languages and the person's exposure to multiple of them.\nIf you have a guy who worked on non-Microsoft platforms, it will be much easier to make him understand why the automated builds, scripted installs and all that old fashioned command line stuff is so important - because that person will see the value and power of scripting, repeatability and automation. This is very hard to explain to a guy who was all his life just clicking buttons and checkboxes in GUI tools and the black box of command line prompt either scares or annoys him. (OK, let's be fair here: until Powershell's availability, the command prompt in Windows was both scary in its ineptitude and annoying compared to e.g. Bash)\nIf you have a seasoned Oracle database guy who used the database on Solaris, Linux and Windows, you will never have to mentioned and explain that you need scripts for things like create schema, load demo data etc. You will get nice, handwritten, commented, parametrized scripts for everything whether you ask for it or not. These guys just operate that way because until recently there was no GUI and because this is fastest way (hi Bob :-)). On the other hand - ask a SQL Server database developer to work using \"script first\" approach and you may find out that it is something not so obvious, the guy does not get it (just keeps on clicking in Management Studio) and that the scripts you eventually get are far from good - because they are generated from changes done via GUI, not really written. To be left maintaining such code - good luck.\nSo what is the best hire ? Smart people, with good education and problem solving capabilities, with solid verifiable experience, wide multicultural background (in the computing sense), with proven record of working in teams of various sizes and ideally well versed in business area you are working in, with work ethic compatible to your organization, shared communication culture and similar degree of done. It does not really matter how many keywords does the resume match: if you need to have great C# programmer and have a choice of experienced Java guy who never touched .Net and 10 year senior Windows programmer who spend most of his/her career on Visual Basic like platforms, it will typically end up like this: Pick a good Java guy, give him 4-6 weeks and the reward will be beautiful, maintainable code with very natural C-sharpness. Pick a VB guy, you will \"save\" the start time - but you will more likely get average, harder to manage, less scalable code because the object design and object thinking just are not there to the same degree as in Java case. The longer the time was spent on VB version 6 or less, the worse.\nAn advanced apology to all my VB.NET loving, VB.NET writing friends - please no flame wars, all of you absolutely are the exceptions confirming the rule, you are the crowd who gets the OOP, and besides we all know that VB.NET is just syntactic sugar on top of C#, of course the \"better\" type of sugar :-). I am not picking on you. I said VB but I really meant Perl ...\nAnd btw, Tidlo - if you are reading this, send me an email. Hope you are still programming and occasionally compiling after you fix the bug.\n","date":"February 21, 2007","externalUrl":null,"permalink":"/posts/2007-02-21-hiring-a-programmer-or-degrees-of-done/","section":"Posts","summary":"Back in old country, I once had a programmer working for me who made himself famous with the following quote:\n\"I have fixed that bug, do you want me to compile it too ?\".\nIn his mind, he was done as soon as he identified the bug and put the fix in the code. All the rest was trivial and unimportant routine.\nDuring last 20 years I have worked with many very different developers and learned the hard way, how very many different meanings the word \"done\" can have. For some, done means that coding just finished and he/she successfully compiled the projects and stepped through some of the code paths with debugger with negligible occurrences of major crash. Whether the code is in CVS, commented - who cares ?\n","title":"Hiring programmers - or Degrees of Done","type":"post"},{"content":"","date":"February 21, 2007","externalUrl":null,"permalink":"/tags/quality/","section":"Tags","summary":"","title":"Quality","type":"tags"},{"content":"Continuing from here.\nCh-7: Digging into the source code\nIn this chapter, Mike describes the tools that work with, around or towards source code: Idlasm, Reflector and FxCop. The book is written for Visual Studio 2003, so some references are slightly outdated - but there is one utility that stands out and is still more useful than ever: Lutz Roeder's Reflector. It is part of the Visual Studio 2005 (albeit in older version that you can get on the Web site).\nHere is in a nutshell what does it do for you: it lets you load a compiled assembly (.exe or .dll), shows content of all classes, functions, etc contained in that assembly. It contains built-in disassembler, which is amazingly good. It also contains analyzer, which shows you - at binary level - what functions/methods are called from a given class method or which classes call this method as well as inter-assembly dependencies. Extremly valuable when debugging some low level DLL loading issues.\nReflector has also inspired many add-ins: see the Lutz's blog, or Add-Ins page on CodePlex. The addins do lot of different things: compute and display code metrics, allow to do binary compare of different versions of same assembly, graphically display interdependencies between assemblies, generate unit test stubs ... make your choice.\n","date":"February 20, 2007","externalUrl":null,"permalink":"/posts/2007-02-20-dotnet-development-toolbox-ii/","section":"Posts","summary":"Continuing from here.\nCh-7: Digging into the source code\nIn this chapter, Mike describes the tools that work with, around or towards source code: Idlasm, Reflector and FxCop. The book is written for Visual Studio 2003, so some references are slightly outdated - but there is one utility that stands out and is still more useful than ever: Lutz Roeder's Reflector. It is part of the Visual Studio 2005 (albeit in older version that you can get on the Web site).\n","title":"DotNet Development Toolbox - II","type":"post"},{"content":"1960\nA logger sells a truckload of lumber for $100. His cost of production is 4/5 of this price. What is his profit?\n1970 (Traditional)\nA logger sells a truckload of lumber for $100. His cost of production\nis 4/5 of this price, or in other words, $80. What is his profit?\n1970 (New Math)\nA logger exchanges a set L of lumber for a set M of money. The cardinality of set M is 100 and each element is worth a dollar. Make a square array of 100 dots to represent the elements of set M. The set C of the cost of production contains 20 fewer elements than set M. Represent set C as a subset of K and answer the following question:\nWhat is the cardinality of set P of profits?\n1980\nA logger sells a truckload of lumber for $100. His cost of production is $80 and his profit is $20. Your assignment is to underline the number 20.\n1990 (Outcomes-based destreamed integrated Math)\nBy cutting down beautiful forest trees, an environmentally ignorant logger makes a profit of $20. What do you think of this way of making a living? In your group, use role play to determine how the forest birds and squirrels feel.\nSource: http://seanm.ca:70/stuff/math-problem.txt ","date":"February 19, 2007","externalUrl":null,"permalink":"/posts/2007-02-19-evolution-of-the-math-problem-or-dumbing-down-the-recent-grads/","section":"Posts","summary":"1960\nA logger sells a truckload of lumber for $100. His cost of production is 4/5 of this price. What is his profit?\n1970 (Traditional)\nA logger sells a truckload of lumber for $100. His cost of production\nis 4/5 of this price, or in other words, $80. What is his profit?\n1970 (New Math)\nA logger exchanges a set L of lumber for a set M of money. The cardinality of set M is 100 and each element is worth a dollar. Make a square array of 100 dots to represent the elements of set M. The set C of the cost of production contains 20 fewer elements than set M. Represent set C as a subset of K and answer the following question:\nWhat is the cardinality of set P of profits?\n","title":"Evolution of the math problem or dumbing down the recent grads","type":"post"},{"content":"","date":"February 18, 2007","externalUrl":null,"permalink":"/tags/book/","section":"Tags","summary":"","title":"Book","type":"tags"},{"content":"I have recently picked very interesting book that I have read about year ago, from Mike Gunderloy named Coder to Developer, with subtitle Tools and Strategies for Delivering Your Software. It is an excellent book and I highly recommend to give it a look if you are in software development business on Microsoft platform. Easy read, practical, useful.When I was reading it back in 2006, it was before we have set up own development lab and started the biometric project. With this recent experience, I was re-reading the book with quite different view: unlike before, I knew what we tried, what worked and what did not. Unlike before, I have now broader experience with what it means developing software and run large project inside the organization, creating and maintaining infrastructure for team of developers and leading the project design and implementation.\nBook has 14 chapters, addressing various areas from starting a new project, organizing it, using tools such as source control, unit testing, IDE, bugtracking, logging, build tools etc. While starting up the lab and the biometric project, we had to go through pretty much every book chapter. Sometimes we made same choice as Mike recommends, sometimes different. Here is our toolbox, in order of the book chapters:\nCh-3 - Source code control\nMike is mentioning several Source code control systems: BitKeeper, ClearCase, CVS, Subversion, Perforce, VSS. We have excluded VSS (because of the reliability), ClearCase (because of complexity and price) and the final selection was done between CVS and Subversion. Actually, between CVS-NT and Subversion. We have decided to adopt both, starting with CVS, because it was more familiar for majority of the team members.\nAt the beginning, we were considering VSTS, but the prohibitive price, complexity and low version number were reason why we decided to wait for at least Service Pack 2 before considering it.\nCh-5 - Unit Testing\nCompared to other projects, we managed to be quite successful in implementing unit tests and TDD. The BO layer has over 100 unit tests which helped to catch several pretty vicious bugs in early days. We settled upon using MbUnit, instead of NUnit, because of very useful extensions such as row tests. MbUnit is pretty much superset of NUnit - see more at project Wiki page. MbUnit works very well, the only disadvantage is very limited documentation.\nCh-6 - IDE\nVisual studio - what else ? In version 2005 it provides very good featureset. Refactoring support is still not quite as comprehenshive as in Eclipse, but very good nevertheless. Some developers use special plugins - e.g. Visual AssistX, but others (including myself) found it rather contraintuitive and liked plain VS.NET better.\nOne of the plugins that we evaluated and actually liked, was Testdriven.NET - nice VS addin to use MbUnit, csUnit and NUnit. Unfortunately, the publisher has very strange licensing policy: the more licenses you buy, the more you pay : Professional license costs $95, but if you need more than one you must purchase Enterprise version ($135). Out of principle, to be \"voting with our dollars\" we decided not to go with Testdriven.Net. Let's hope that more people will do the same and eventually, the author will get the message.\nTo be continued\n","date":"February 18, 2007","externalUrl":null,"permalink":"/posts/2007-02-18-dotnet-development-toolbox/","section":"Posts","summary":"I have recently picked very interesting book that I have read about year ago, from Mike Gunderloy named Coder to Developer, with subtitle Tools and Strategies for Delivering Your Software. It is an excellent book and I highly recommend to give it a look if you are in software development business on Microsoft platform. Easy read, practical, useful.When I was reading it back in 2006, it was before we have set up own development lab and started the biometric project. With this recent experience, I was re-reading the book with quite different view: unlike before, I knew what we tried, what worked and what did not. Unlike before, I have now broader experience with what it means developing software and run large project inside the organization, creating and maintaining infrastructure for team of developers and leading the project design and implementation.\n","title":"DotNet Development Toolbox","type":"post"},{"content":"Few of my favorites:\nMost software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. [Alan Kay]\nHofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.\nDebugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. [Brian W. Kernighan]\nThe primary duty of an exception handler is to get the error out of the lap of the programmer and into the surprised face of the user. Provided you keep this cardinal rule in mind, you can't go far wrong.[Verity Stob]\nProgramming can be fun, so can cryptography; however they should not be combined.[Kreitzberg and Shneiderman]\nThe best performance improvement is the transition from the nonworking state to the working state [John Ousterhout]\nI have always wished that my computer would be as easy to use as my telephone. My wish has come true. I no longer know how to use my telephone. [Bjarne Stroustrup]\nTheory is when you know something, but it doesn't work. Practice is when something works, but you don't know why.\nProgrammers combine theory and practice: Nothing works and they don't know why. [Anonymous]\nFor every complex problem there is an answer that is clear, simple, and wrong. [H L Mencken]\nOne of the main causes of the fall of the Roman Empire was that, lacking zero, they had no way to indicate successful termination of their C programs. [Robert Firth]\n...well over half of the time you spend working on a project (on the order of 70 percent) is spent thinking, and no tool, no matter how advanced, can think for you. Consequently, even if a tool did everything except the thinking for you -- if it wrote 100 percent of the code, wrote 100 percent of the documentation, did 100 percent of the testing, burned the CD-ROMs, put them in boxes, and mailed them to your customers -- the best you could hope for would be a 30 percent improvement in productivity. In order to do better than that, you have to change the way you think. [Fred Brook]\nNever attribute to malice that which is adequately explained by stupidity. [Hanlon's razor]\nSufficiently advanced incompetence is indistinguishable from malice. [Anon]\nFor more, try this, this or this.\n","date":"February 17, 2007","externalUrl":null,"permalink":"/posts/2007-02-17-programmers-and-programming-in-quotes/","section":"Posts","summary":"Few of my favorites:\nMost software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves. [Alan Kay]\nHofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.\nDebugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. [Brian W. Kernighan]\n","title":"Programmers and programming in quotes","type":"post"},{"content":"","date":"February 16, 2007","externalUrl":null,"permalink":"/tags/media/","section":"Tags","summary":"","title":"Media","type":"tags"},{"content":"It is Friday again, time to clean up the link cache. I'll try to make this a Friday affair and stick with weekly schedule.\nThe DRM is having hard time: after Steve Jobs article about how DRM is bad, EMI announcement of considering dropping the DRM, another of Net celebrities - cryptography legend Bruce Schneier (of Applied Crypography and Blowfish fame) wrote an article for Forbes Why Vista DRM Is Bad for you. He makes several good points, it is good read.\nInteresting article on using Google as office platform - beyond Google for domains. Do you know what are the 3 largest databases of the world? Not Google, it is actually #4. Its World Data Centre for climate, followed by National Energy Research Centre and AT\u0026amp;T. Hard to believe ? Here you find top ten.\nIn the .NET world - Scott Hanselman has interesting article on Static Code analysis with NDepend. Few interesting findings from CodeProject: Record Versioning with SQL Server, Marc Clifton has new article on Disconnected Client Architecture (Marc writes great advanced level articles, look around), How to use extended properties to create self-documenting databases. Nice gauge controls for Winforms.\nOn Mac side: yet another list of best Mac resources. Rant about Quartz Composer. Release Candidate 3 of Parallels is out and it is Leopard ready (to run under Leopard, not to virtualize OS-X). Even Second Life already has Apple Store. Why does not Ottawa have one ?\nFrom a business law world - for newbies like myself, nice and understandable explanation of the difference between an IPO and reverse merger through a public shell. Nice video on Google master plan.\n","date":"February 16, 2007","externalUrl":null,"permalink":"/posts/2007-02-16-webbits-2007-04/","section":"Posts","summary":"It is Friday again, time to clean up the link cache. I'll try to make this a Friday affair and stick with weekly schedule.\nThe DRM is having hard time: after Steve Jobs article about how DRM is bad, EMI announcement of considering dropping the DRM, another of Net celebrities - cryptography legend Bruce Schneier (of Applied Crypography and Blowfish fame) wrote an article for Forbes Why Vista DRM Is Bad for you. He makes several good points, it is good read.\n","title":"Webbits 2007-04","type":"post"},{"content":"Connie, our HR director came few weeks ago with interesting idea: give the team a chance to get better understanding of \"implementation details\" of their very own \"inner software\" - the personality type evaluation using Myers-Briggs approach. Connie holds certification for this type of classification.\nThe classification in a nutshell, assigns to everybody four letters, one from each pair: E or I, N or S, T or F, J or P. The first letter indicates preference for Extraversion or Introversion, the second characterizes the main source of information input: Sensation or iNtuition, the third the way how the information is processed - by Thinking or Feeling and the last one characterizes the degree of \"structure\" and organization in all the previous: more organized and structured (Judging) or less organized and more ad-hoc (Perceiving). Now all this is terrible oversimplification (sorry Connie), so if you really want to get more information try this - or if you are in Ottawa, call Connie Deschamps at Thinknostic dot com and schedule a session :-).\nThe evaluation consists of three parts:\n- self-service questionnaire consisting of 93 questions via Web\n- review and validation in 1:1 session\n- the workshop\nDuring last two weeks we have done round of Meyers-Briggs evaluation in the Thinknostic employee team. Not a big surprise, we ended up being heavier on I and T types (which is implied by the type of business we are in), as well as very heavy on N and P - which may be related to relatively small size and start-up phase of the company.\nThe really interesting part was the workshop, which consisted of exercises showing how different types process/think differently. Even if you know who is who (we have agreed to share our results) - it is amazing to see the differences at work. It was real eye opener for several people, including myself. I think that the more away you are from SF (the more away from pragmatic people-oriented focus you have), the more surprises and really new information you may get. I certainly learned few things (being an INTP) and will try to remember it next time I may be dealing with people who kind of seems to be \"just incompatible\" with my way of seeing the world. I will try harder - as somebody did put it nicely \"... to respect our different points of view, however wrong yours may be\" :-)\nWhy understanding of this things matters ? One area that is very obvious are different methodologies and approaches to personal productivity, for example GTD. They seem to work extremely well for certain people, sort-of-work for some and fail miserably for others. I have nagging suspicion that these tools and software based on them are heavily oriented towards the J types, and even more towards SJ combinations (the I-E and T-F preference have probably lesser impact).\nThe portions of GTD that work well for NP's are \"calendar tickle file\" - you need future reminders when you operate in ad-hoc mode and do not naturally follow repetitive schedules. You also need to use lists - but you use them in different context. While for SJ people the list is sequence of steps, a plan of execution (often hierarchical) for N it is mixture of list-of-alternatives, steps and ideas, usually all overlapping and interconnected - more hypertext than a linear list. The part of GTD that NP like me has biggest trouble with are the weekly reviews.\nOn the other hand, exactly these areas that are natural for SJ can be biggest gain for NP's if we can find the software or tool that makes it us more like SJ - but the NP way. Is there such software ?\nAs the long tail and spaghetti sauce teaches us, the future is in selling less to more. Maybe considering writing customized PIM for the personality type is not such crazy idea after all. What do you think ?\n","date":"February 15, 2007","externalUrl":null,"permalink":"/posts/2007-02-15-on-myers-briggs-spaghetti-sauce-and-getting-things-done/","section":"Posts","summary":"Connie, our HR director came few weeks ago with interesting idea: give the team a chance to get better understanding of \"implementation details\" of their very own \"inner software\" - the personality type evaluation using Myers-Briggs approach. Connie holds certification for this type of classification.\nThe classification in a nutshell, assigns to everybody four letters, one from each pair: E or I, N or S, T or F, J or P. The first letter indicates preference for Extraversion or Introversion, the second characterizes the main source of information input: Sensation or iNtuition, the third the way how the information is processed - by Thinking or Feeling and the last one characterizes the degree of \"structure\" and organization in all the previous: more organized and structured (Judging) or less organized and more ad-hoc (Perceiving). Now all this is terrible oversimplification (sorry Connie), so if you really want to get more information try this - or if you are in Ottawa, call Connie Deschamps at Thinknostic dot com and schedule a session :-).\n","title":"On Myers-Briggs, Spaghetti Sauce and Getting Things Done","type":"post"},{"content":"On Tuesday evening, the Ottawa Dotnet Users Group organized presentation of Adam Machanic from Boston with title \"Designing Highly Concurrent SQL Server Database Applications\". I was not sure whether I will make it, because because I did not feel really well, but I am very happy I went.\nIt was probably one of the best presentations I have seen in Microsoft Glacier Room on 100 Queen Street. I am not sure whether because it was indeed so great or because it touches closely what we are doing.\nWhat was great on the lecture was lack of dependency on SQL server. Technically, most modern databases could be used and the techniques would still work. We are going to stay with SQL 2005 which is btw one very decent, well performing, easy to install and manage database system - but learning something portable is always a pleasure.\nThe presentation covered two classical way how to handle concurrency - pessimistic and optimistic and presented quite clever way how to do it without stored procedures. It also covered the \"multi value\" approach, which replaces update with inserts and maintain multiple copies of each record. This is btw, very close to what we are doing in Tirevigil Navigator - keeping full history of tire and vehicle data.\nAdam is an co-author of Pro SQL Server 2005 as well as blogger: see this and this . His new book Expert SQL Server 2005 Development is about to be published in March - I will definitely give it a serious look.\nYou can grab the slides and source code from the presentation here.\n","date":"February 14, 2007","externalUrl":null,"permalink":"/posts/2007-02-14-handling-concurrency-in-sql-server-applications/","section":"Posts","summary":"On Tuesday evening, the Ottawa Dotnet Users Group organized presentation of Adam Machanic from Boston with title \"Designing Highly Concurrent SQL Server Database Applications\". I was not sure whether I will make it, because because I did not feel really well, but I am very happy I went.\nIt was probably one of the best presentations I have seen in Microsoft Glacier Room on 100 Queen Street. I am not sure whether because it was indeed so great or because it touches closely what we are doing.\n","title":"Handling concurrency in SQL Server applications","type":"post"},{"content":"I found out by accident that the famous Get a Mac ads exists in many versions:\nSome nations have their own actors\nhttp://www.apple.com/uk/getamac/ads/\nhttp://www.apple.com/jp/getamac/ads/\nOther have only just language version of Long \u0026amp;\u0026amp; Hodgman act\nhttp://www.apple.com/de/getamac/ads/\nhttp://www.apple.com/fr/getamac/ads/\nhttp://www.apple.com/it/getamac/ads/\nhttp://www.apple.com/es/getamac/\nThe Austria and German speaking part of Switzerland are using German version of the ads (no surprise there) - http://www.apple.com/chde/getamac/ - and the francophone part of Switzerland uses the French version. As it looks like, Italian and Romansch speaking Swiss do not count :-(\nThe Dutch, Swedes, Finns and so on do not need any translation:\nhttp://www.apple.com/nl/getamac/\nhttp://www.apple.com/se/getamac/\nhttp://www.apple.com/fi/getamac/\nhttp://www.apple.com/no/getamac/\nAnd obviously, neither did Australia and New Zealand :-)\n","date":"February 13, 2007","externalUrl":null,"permalink":"/posts/2007-02-13-many-ways-how-to-get-a-mac/","section":"Posts","summary":"I found out by accident that the famous Get a Mac ads exists in many versions:\nSome nations have their own actors\nhttp://www.apple.com/uk/getamac/ads/\nhttp://www.apple.com/jp/getamac/ads/\nOther have only just language version of Long \u0026\u0026 Hodgman act\nhttp://www.apple.com/de/getamac/ads/\nhttp://www.apple.com/fr/getamac/ads/\nhttp://www.apple.com/it/getamac/ads/\nhttp://www.apple.com/es/getamac/\nThe Austria and German speaking part of Switzerland are using German version of the ads (no surprise there) - http://www.apple.com/chde/getamac/ - and the francophone part of Switzerland uses the French version. As it looks like, Italian and Romansch speaking Swiss do not count :-(\n","title":"Many ways how to \"Get a Mac\"","type":"post"},{"content":"After lots of attempts (see here, here and here), I have finally resolved my disk space problems and the RAID-5 NAS server is up and running since about two weeks now. I have stayed with Fedora 6, successfully installed Samba, configured the shares and copied all family JPEG's, videos, MP3's etc onto the huge 907 GB large RAID5 share. The old NSLU2 is still dead - I did not have any time to try to re-flash it, but all content of it's disk was without any issues readable by the new server (the NSLU2 was using ext3 filesystem) so I did not even have to try to use backups.\nMost of things in Fedora can be configured graphically. The only case I had to go to shell were final configuration changes in Samba. As it turned out, the default umask allowed search on directories (rwxr-xr-x), but none on files (rwx------). This lead to strange behaviour when the images were visible from Windows client - user could see the file names in the directory but no viewer could display them. Fix was trivial:\nfind . -name \"*.jpg\" -exec chmod +r '{}' \\;\nIt's kind of funny how old skills reapper when you need them. Unix is like riding a bike: you get uncomfortable and out of form but you never loose it completely. I even remembered quite a few vi and emacs key combinations (but happily switched to use gedit or JEdit).\nOne thing that did not work out of the box was VNC server (I am getting ready to disconnect monitor and keyboard, move the box under the desk and forget about it for next year or so :-)). When attempting to start the VNC server using the GUI interface - it does not report any error, but does not start either. When trying from command line (using /sbin/service), the error explained the problem with Xstartup. I found this useful info, will try it out.\nSo far I am very happy with performance of the system (I have copied about 150 GB of content on the NAS).\nLessons learned:\n- the \"NAS\" like distributions (FreeNAS, NASLite+) have variety of limitations (like lack of readonly/readwrite access support, user access rights) and are basically all-or-nothing solutions\n- OpenFiler is not good solution for home network either. It goes to the other extreme - unless you have domain controller, you are out of luck, as it does not support local users\n- from full distributions, Fedora provides everything you need to have NAS as well as well user friendly environment for administration. To be fair, I did not try OpenSUSE or Mandriva. Ubuntu - despite being known as the \"most user friendly\" distro did not work for me: the desktop edition (which indeed was great user experience) does not contain server components and the server edition requires really experienced Linux admin as it has no GUI at all.\nAll summed up: lots of fun. Worth every penny.\n","date":"February 12, 2007","externalUrl":null,"permalink":"/posts/2007-02-12-nas-odyssey-up-and-running/","section":"Posts","summary":"After lots of attempts (see here, here and here), I have finally resolved my disk space problems and the RAID-5 NAS server is up and running since about two weeks now. I have stayed with Fedora 6, successfully installed Samba, configured the shares and copied all family JPEG's, videos, MP3's etc onto the huge 907 GB large RAID5 share. The old NSLU2 is still dead - I did not have any time to try to re-flash it, but all content of it's disk was without any issues readable by the new server (the NSLU2 was using ext3 filesystem) so I did not even have to try to use backups.\n","title":"NAS Odyssey: Up and running","type":"post"},{"content":"Depending on how you define success, you may get different answer to the question above.\nIf you choose for the success criteria:\n- amount of money made by programming AND\n- number of people using the product AND\n- impact on the community at large\nthe answer is probably Charles (Karoly) Simonyi, Hungarian born ex-Microsoft employee, billionaire, astronaut and original author of Microsoft Word.\nTrue, there certainly are people that made more money than him and their fortune is closely related to software - but unlike Simonyi none of them was actively programming for major part of their career. Take Bill Gates for example - most of his coding goes back to his teenage years and after creating Basic, his role was not related with active code writing. Also the number of people using Altair Basic (or any basic) today is likely nowhere in the Word league.\nSimonyi is also creator of contraversial Hungarian naming notation of variables, which was considered to be \"canonical\" notation for programming Windows with C and C++, popularized by another Charles, the author of de-facto standard Windows programming textbook - Charles Petzold. In a nutshell, Hungarian notation adds prefix to each variable name which encodes its data type: for example: char *lpszBuffer means long pointer to string (zero-terminated).\nThe supporters say that this allows easy visual control of how the variables are used, e.g. from:\nstrcpy(lpszBuff, \u0026amp;cName);\nis obvious (at least for experienced C programmer) that the code will crash, because the right side is an address of single byte character, not a string and there is no terminating zero after the byte, therefore the strcpy will likely overwrite the buffer and possibly stack.\nThe opponents say that modern languages and modern compilers make most of these checks available in the compiler and that the name should denote what is the role/purpose of the variable, not it's type - as the type can easily change. Roedy Green calls Hungarian Notation \"the tactical nuclear weapon of source code obfuscation techniques.\" (see his recommendation How to write unmaintainable code and Mozilla programmer Alec Flett wrote (using Hungarian Notation):\n\"prepBut nI vrbLike adjHungarian! qWhat's artThe adjBig nProblem?\nHow did I get to writing about Charles Simonyi ausgerechnet today ? The MIT Technology Review published fairly interesting article on him and his latest brainchild - Intentional Programming. The article is fairly long read, but quite interesting. The goals of Intentional Programming are very ambitious and it is hard to say, how realistic is it to achieve them at all. The domain specific languages are certainly fashionable and idea of having \"WYSIWYG\" for graphical construction of code is attractive. But is it doable ? The details on are sketchy and without trying it out, it is hard to make any opinion - but it looks much more like interesting research concept than the production-ready system.\nTake the example on Page 13 - it reminds me a lot of what I have seen during my PhD studies: a system that works for some very narrow, textbook size example - small, well defined problem with perfectly described boundaries and no inter-dependencies, but is just impractical for any real life application. Metaprogramming is still one of the many Holy Grails of software engineering - and we often get confused by believing that adding another level of indirection will substantially change the nature of the problem on hand ...\nIMHO best quote from the article was the Wirth's Law (after Niklaus Wirth):\n\"Software gets slower faster than hardware gets faster.\"\nThis is so true, especially if you look on Vista's hardware requirements and think for a moment about your subjective feeling how responsive is your brand new, 2 GHZ dual core notebook with 2GB RAM running Vista. Now try to think few years back (if you can go back to 1998-99) and compare this to the state-of-the-art machine you were using at that time - probably something like a single core 300-450 MHz Pentium II with 128 MB RAM running Windows NT 4. How did that feel ?\nAs far as I can remember, the feeling was about the same - while doing the same things - develop software, browse Web, write documents and do emails - the old notebook did not perform considerably worse, certainly not 2-3 times worse. So despite the 10 times increase in RAM size, speed/CPU power, disk size and disk speed, we have not gained much on the user responsiveness side. Vista looks much nicer, but the feeling of speed is the same ... only software is many times more bloated.\n","date":"February 11, 2007","externalUrl":null,"permalink":"/posts/2007-02-11-who-is-the-most-successful-programmer-of-the-world/","section":"Posts","summary":"Depending on how you define success, you may get different answer to the question above.\nIf you choose for the success criteria:\n- amount of money made by programming AND\n- number of people using the product AND\n- impact on the community at large\nthe answer is probably Charles (Karoly) Simonyi, Hungarian born ex-Microsoft employee, billionaire, astronaut and original author of Microsoft Word.\nTrue, there certainly are people that made more money than him and their fortune is closely related to software - but unlike Simonyi none of them was actively programming for major part of their career. Take Bill Gates for example - most of his coding goes back to his teenage years and after creating Basic, his role was not related with active code writing. Also the number of people using Altair Basic (or any basic) today is likely nowhere in the Word league.\n","title":"Who is the most successful programmer of the world ?","type":"post"},{"content":"","date":"February 10, 2007","externalUrl":null,"permalink":"/tags/math/","section":"Tags","summary":"","title":"Math","type":"tags"},{"content":"I've stumbled upon this page, full of math jokes. Many of them are IMHO really good and extremly funny (your mileage may vary, though).\nMy favorite few:\nTwo male mathematicians are in a bar. The first one says to the second that the average person knows very little about basic mathematics. The second one disagrees, and claims that most people can cope with a reasonable amount of math.\nThe first mathematician goes off to the washroom, and in his absence the second calls over the waitress. He tells her that in a few minutes, after his friend has returned, he will call her over and ask her a question. All she has to do is answer one third x cubed.\nShe repeats \"one thir -- dex cue\"?\nHe repeats \"one third x cubed\".\nHer: `one thir dex cuebd'? Yes, that's right, he says. So she agrees, and goes off mumbling to herself, \"one thir dex cuebd...\".\nThe first guy returns and the second proposes a bet to prove his point, that most people do know something about basic math. He says he will ask the blonde waitress an integral, and the first laughingly agrees. The second man calls over the waitress and asks \"what is the integral of x squared?\".\nThe waitress says \"one third x cubed\" and while walking away, turns back and says over her shoulder \"plus a constant!\"\nand\nA mathematician organizes a lottery in which the prize is an infinite amount of money. When the winning ticket is drawn, and the jubilant winner comes to claim his prize, the mathematician explains the mode of payment: \"1 dollar now, 1/2 dollar next week, 1/3 dollar the week after that...\"\nand\nA famous mathematician was to give a keynote speech at a conference. Asked for an advance summary, he said he would present a proof of Fermat's Last Theorem -- but they should keep it under their hats. When he arrived, though, he spoke on a much more prosaic topic. Afterwards the conference organizers asked why he said he'd talk about the theorem and then didn't. He replied this was his standard practice, just in case he was killed on the way to the conference.\nthe last one - in memory of John von Neumann:\nThe following problem can be solved either the easy way or the hard way.\nTwo trains 200 miles apart are moving toward each other; each one is going at a speed of 50 miles per hour. A fly starting on the front of one of them flies back and forth between them at a rate of 75 miles per hour. It does this until the trains collide and crush the fly to death. What is the total distance the fly has flown?\nThe fly actually hits each train an infinite number of times before it gets crushed, and one could solve the problem the hard way with pencil and paper by summing an infinite series of distances. The easy way is as follows: Since the trains are 200 miles apart and each train is going 50 miles an hour, it takes 2 hours for the trains to collide. Therefore the fly was flying for two hours. Since the fly was flying at a rate of 75 miles per hour, the fly must have flown 150 miles. That's all there is to it.\nWhen this problem was posed to John von Neumann, he immediately replied, \"150 miles.\"\n\"It is very strange,\" said the poser, \"but nearly everyone tries to sum the infinite series.\"\n\"What do you mean, strange?\" asked Von Neumann. \"That's how I did it!\"\n","date":"February 10, 2007","externalUrl":null,"permalink":"/posts/2007-02-10-math-is-fun/","section":"Posts","summary":"I've stumbled upon this page, full of math jokes. Many of them are IMHO really good and extremly funny (your mileage may vary, though).\nMy favorite few:\nTwo male mathematicians are in a bar. The first one says to the second that the average person knows very little about basic mathematics. The second one disagrees, and claims that most people can cope with a reasonable amount of math.\nThe first mathematician goes off to the washroom, and in his absence the second calls over the waitress. He tells her that in a few minutes, after his friend has returned, he will call her over and ask her a question. All she has to do is answer one third x cubed.\n","title":"Math is fun","type":"post"},{"content":"1) Bruce Schneier\nBruce is author of several excellent books on cryptography, from very easy, thriller like read to a classic work Applied Cryptograhy (highly recommended). The blog goes back to 2004 and is fascinating read.\n2) Paul Thurrott\nPaul is the Windows guy from Windows Weekly podcast (recommended) who also runs the Winsupersite . He is one of the few people who focus on Microsoft technology and still keep balanced, fair view of the affairs. Paul is certainly not a Microsoft fanboy - and obviously not a Microsoft hater. He seems to share the same balanced approach in case of Apple and OS-X - he appreciates his strengths without being an Apple zealot.\n3) Cedrik's Weblog\nGoogle engineer, creator of the TestNG framework, writing mostly on Java and test driven development. I was fairly deep involved recently in unit testing (mostly in .NET world) and discovered there is a lot of interesting tools and frameworks available beyond the JUnit/NUnit boundaries. But that is topic for the other time.\n","date":"February 9, 2007","externalUrl":null,"permalink":"/posts/2007-02-09-blogs-of-the-week-9-feb/","section":"Posts","summary":"1) Bruce Schneier\nBruce is author of several excellent books on cryptography, from very easy, thriller like read to a classic work Applied Cryptograhy (highly recommended). The blog goes back to 2004 and is fascinating read.\n2) Paul Thurrott\nPaul is the Windows guy from Windows Weekly podcast (recommended) who also runs the Winsupersite . He is one of the few people who focus on Microsoft technology and still keep balanced, fair view of the affairs. Paul is certainly not a Microsoft fanboy - and obviously not a Microsoft hater. He seems to share the same balanced approach in case of Apple and OS-X - he appreciates his strengths without being an Apple zealot.\n","title":"Blogs of the week (9-Feb)","type":"post"},{"content":"How to extend the life of the Vista trial period to 120 days: Technically, if you try to use Ultimate Edition (which is legally allowed to use in VM) nothing really can prevent an unscrupulous user to keep using Vista for free - for the price of re-installing the VM every 120 days ...\nFew Mac goodies: Adium is out in version 1.0 - get it here - more details on http://adiumx.com/\nLast build before Leopard is out - http://www.thinksecret.com/news/0702.html. Btw, did you know that Apple UK has their own Mac guy and PC guy ? I love their accent, but I still think that John Hodgman is the best :-)\nNice collection of free fonts.\nNice way how to synchronize the GCalendar with iCal.\nBeautiful visualizations - http://visualcomplexity.com/vc/\nEconomy of Bandwith - http://www.codinghorror.com/blog/archives/000783.html\nFive minutes video on \"What is Web 2.0\"\n","date":"February 8, 2007","externalUrl":null,"permalink":"/posts/2007-02-08-webbits-2007-03/","section":"Posts","summary":"How to extend the life of the Vista trial period to 120 days: Technically, if you try to use Ultimate Edition (which is legally allowed to use in VM) nothing really can prevent an unscrupulous user to keep using Vista for free - for the price of re-installing the VM every 120 days ...\nFew Mac goodies: Adium is out in version 1.0 - get it here - more details on http://adiumx.com/\nLast build before Leopard is out - http://www.thinksecret.com/news/0702.html. Btw, did you know that Apple UK has their own Mac guy and PC guy ? I love their accent, but I still think that John Hodgman is the best :-)\n","title":"Webbits - 2007-03","type":"post"},{"content":"Back in stone age when most information available was actually printed on paper in forms of magazines and books , people experiencing the information overload invented techniques of speed reading to deal with it.\nIt worked - mostly.\nNowadays, we have most of the content coming to you through the browser window. Even if you can still speed read the web page, you can get even more speed advantage and quickly sort out the interesting content from the fluff by using the magic of news feeds, RSS, Atom and wonderful free tool Google Reader.\nRather that going to tens of favorites news web sites, blogs, etc you just subscribe to their feeds and the reader will show you whenever there is something new of interest. It also allows you to classify - tag the feeds and create groups, for example of Windows related blogs/news sites versus Apple related. It is completely up to you. You can also (as in Gmail) to \"star\" the favorite articles to keep them marked (or, to save a local copy in Google Notebook).\nI have started to use the Reader again two weeks ago and never looked back. Now I have all my favorite feeds in one place and whenever I have some time (pretty rarely these days) I am trying to catch up. What I found very cool is bunch of tricks described in this lifehacler article.\nMy favorites are g+u keys as well as g+t/g+l keystrokes. Try them out.\nAnd now for something completely different: tomorrow it will be 50 years from the death of the John von Neumann (or as he is known him in our geo-region - Neumann János (he was born in Budapest, Austria-Hungary in 1903). A computer science pioneer and world class mathematician. If the computer science, mathematics, physics had their own Halls of Fame - similar as the Hockey Hall of Fame - he would have place in all of them.\n","date":"February 7, 2007","externalUrl":null,"permalink":"/posts/2007-02-07-surf-more-in-less-time-google-reader/","section":"Posts","summary":"Back in stone age when most information available was actually printed on paper in forms of magazines and books , people experiencing the information overload invented techniques of speed reading to deal with it.\nIt worked - mostly.\nNowadays, we have most of the content coming to you through the browser window. Even if you can still speed read the web page, you can get even more speed advantage and quickly sort out the interesting content from the fluff by using the magic of news feeds, RSS, Atom and wonderful free tool Google Reader.\n","title":"Surf more in less time: Google Reader","type":"post"},{"content":"However I like the Web applications, the fact is that as soon as you do not have connectivity, they are of very little use. Well - maybe not for long. The Dojo Offline Toolkit makes promise that sounds almost too good to be true:\nImagine a version of GMail with a “Work Offline” button on the left-hand side of the screen. When pressed, GMail downloads 100 of your most recent emails into Dojo Offline, including pieces of it’s user-interface. A user can now close their browser and leave the network, stepping on an airplane for example. Once in the air, the user can then simply open their laptop and browser and type in mail.google.com. The GMail UI magically appears, along with their 100 most recent emails. A user can read these mails, compose new ones, or reply to existing ones. A flight attendant announces that the plane will land soon; the user closes their browser and laptop. Later, when they are back on the network, they can click the “Work Online” button, which will send all of their locally written emails to the GMail server. or even for Google Docs:\nsimply select which documents you want to have locally. Later, open your browser and navigate to docs.google.com, working from anywhere you want, even without a network. When you are done, press the “Sync” button to send it back to the server with your changes when the network reappears.\nThe technology behind is local proxy with Javascript autoconfiguration and local file cache. It is a project in progress, so unfortunately, you cannot try it out right away :-( - but seems very promising. Best of all, it should be multi platform (Windows, Mac, Linux) and opensource (BSD License).\nCannot wait !\n","date":"February 6, 2007","externalUrl":null,"permalink":"/posts/2007-02-06-offline-access-to-gmail-and-google-docs-coming/","section":"Posts","summary":"However I like the Web applications, the fact is that as soon as you do not have connectivity, they are of very little use. Well - maybe not for long. The Dojo Offline Toolkit makes promise that sounds almost too good to be true:\nImagine a version of GMail with a “Work Offline” button on the left-hand side of the screen. When pressed, GMail downloads 100 of your most recent emails into Dojo Offline, including pieces of it’s user-interface. A user can now close their browser and leave the network, stepping on an airplane for example. Once in the air, the user can then simply open their laptop and browser and type in mail.google.com. The GMail UI magically appears, along with their 100 most recent emails. A user can read these mails, compose new ones, or reply to existing ones. A flight attendant announces that the plane will land soon; the user closes their browser and laptop. Later, when they are back on the network, they can click the “Work Online” button, which will send all of their locally written emails to the GMail server. ","title":"Offline access to GMail and Google Docs coming ?","type":"post"},{"content":"In software industry there are no annual awards and recognitions of achievements that would resemble the Annual Academy Awards of the movie industry. Various magazines, publishers and companies do present theirs yearly list of Best Products, but they are often biased and seldom representative. The one list that stands apart and that in my opinion comes closest the Oscar is Jolt Awards published by used-to-be one of the best magazines for professional programmers - Dr Dobbs Journal. It is still around and still a pretty good magazine, I guess - but the evolution of the Internet and shift of the money towards on-line advertisement changed the business landscape for most of the magazines, depending on revenue stream from ads. The list has various categories: for books (general and technical), project management, database systems and tools, IDE, design tools, development libraries and so on.\nAs with the movies, it is nice to discover that the movie you have seen and liked makes it to the \"Best of ...\" selection. I have noticed that several of my favorite products were listed for this year - namely JIRA, IronPython, Liferay, Textmate, Koders.com and Codeproject.com. For last year, the match was even longer: Visual Studio 2005, SQL Server 2005, MySQL 5.0, JIRA, Enterprise Architect, Eclipse 3.1, Komodo, .NET Framework 2.0, Spring Framework, JBoss.\nGo and have peek. You may discover your favorites in there too - or get some inspiration of the new apps to look at.\n","date":"February 5, 2007","externalUrl":null,"permalink":"/posts/2007-02-05-software-oscar-award/","section":"Posts","summary":"In software industry there are no annual awards and recognitions of achievements that would resemble the Annual Academy Awards of the movie industry. Various magazines, publishers and companies do present theirs yearly list of Best Products, but they are often biased and seldom representative. The one list that stands apart and that in my opinion comes closest the Oscar is Jolt Awards published by used-to-be one of the best magazines for professional programmers - Dr Dobbs Journal. It is still around and still a pretty good magazine, I guess - but the evolution of the Internet and shift of the money towards on-line advertisement changed the business landscape for most of the magazines, depending on revenue stream from ads. The list has various categories: for books (general and technical), project management, database systems and tools, IDE, design tools, development libraries and so on.\n","title":"Software Oscar Award","type":"post"},{"content":"Time to clean up the link cache once again.\nObviously, most of the news on Techsites are Vista related. Web Worker's daily gives you 10 reasons why to upgrade to Vista and 10 reasons why not. MacHouse comments on complicated upgrade paths and Brian Briggs offers decision chart for the updgradees.\nGeneral spirit - compared to the launch of Windows 95 - is fairly cynical. The italian Mac bloggers sums it up: Niente di nuovo in Vista. So does this one. This site shows some real innovation :-). Despite it is Vista launch, Steve Jobs and OS-X seems to get almost as much publicity as Vista and as few bloggers commented - Microsoft does not take it easy - see Bill Gates TV appearance.\nBut back to tech. While organizing my MP3 collection (getting ready to move it up to the NAS), I have found this opensource tool very helpful. One of my countrymen provides service that converts text files to iPod readable eBook format. If you have iPod and do not have eReader, try it out. Good article on using PowerShell to simplify deployment on Windows. Mark Russinovich of the Sysinternals fame started series on Vista Kernel. Sysinternals was acquired by Microsoft which was certainly great for Mark. But is one of the ironies of life that the guy who discovered Sony DRM rootkit in 2005 and started the public outcry which caused the recall of all DRM-ed CD's is now employed by a company which allowed the most aggresive DRM cancer to be part of the the OS kernel ...\nAlso first Vista related hacks are appearing: starting with how to install Vista upgrade on clean machine Also the touted DRM did not last long: two months or one day - depending how you count. See Vista DRM: How fools and their copy-protection investments are always separated, Vista DRM cracked. Register even calls the Windows DRM the 'longest suicide note in history'. Was it really worth to create all the controversy ? Vista has lots to offer - the improvements in usability, security and \"core\" applications are substantial - but the very bad way how the DRM is burried into kernel and stubborn refusal to admit where the new features inspiration came from completely hide that.\nBut enough about Vista. Lifehacker published link to tutorial how to burn almost any video file to playable DVD. If you are not on Mac and miss you Quicksilver, try Launchy. If you are on Mac platform, look at this nice opensource app and read how to better use metadata.\n","date":"February 4, 2007","externalUrl":null,"permalink":"/posts/2007-02-04-webbits-2007-02/","section":"Posts","summary":"Time to clean up the link cache once again.\nObviously, most of the news on Techsites are Vista related. Web Worker's daily gives you 10 reasons why to upgrade to Vista and 10 reasons why not. MacHouse comments on complicated upgrade paths and Brian Briggs offers decision chart for the updgradees.\nGeneral spirit - compared to the launch of Windows 95 - is fairly cynical. The italian Mac bloggers sums it up: Niente di nuovo in Vista. So does this one. This site shows some real innovation :-). Despite it is Vista launch, Steve Jobs and OS-X seems to get almost as much publicity as Vista and as few bloggers commented - Microsoft does not take it easy - see Bill Gates TV appearance.\n","title":"Webbits - 2007-02","type":"post"},{"content":"As of today, I am at podcast #26 of Security Now! and Steve with Leo are have started their \"foundation series\" on How Internet works. It is really great and enjoyable topic, nicely and very enjoyably presented. Given the delivery format limitation (voice without possibility of adding any drawing), there is of course limit on the amount of details that can be presented. Being a curious creature, I wanted to dig little bit deeper into \"excruciating details\" of TCP/IP and started to search for a good book.\nToday at Chapters, I scanned few books and here is the result: What I thought would be the best authoritative guide - The TCP/IP Illustrated - did not work for me. It is supposedly \"the\" book on TCP/IP authored by the Richard Stevens of the Advanced Unix Programming fame (which is a great book), but the writing style is fairly dry and often it looks like you cannot see the forest for the trees.\nFortunately the second book I picked - TCP/IP Guide - was IMHO much better written. And even better, the book's content is available on-line as well. You can read for free on-line or purchase the PDF.\nHooray into the Alphabet soup: ICMP, ARP, RARP, IPSec, CIDR, RIP, OSPF, BGP, OMG ... oops, that is not a protocol :-)\n","date":"February 3, 2007","externalUrl":null,"permalink":"/posts/2007-02-03-nice-resource-on-tcpip-and-networking/","section":"Posts","summary":"As of today, I am at podcast #26 of Security Now! and Steve with Leo are have started their \"foundation series\" on How Internet works. It is really great and enjoyable topic, nicely and very enjoyably presented. Given the delivery format limitation (voice without possibility of adding any drawing), there is of course limit on the amount of details that can be presented. Being a curious creature, I wanted to dig little bit deeper into \"excruciating details\" of TCP/IP and started to search for a good book.\n","title":"Nice resource on TCP/IP and Networking","type":"post"},{"content":"","date":"February 3, 2007","externalUrl":null,"permalink":"/tags/podcasts/","section":"Tags","summary":"","title":"Podcasts","type":"tags"},{"content":"As the tittle says, Fedora Core 6 is it. Everything is installed, everything works. The box is very fast, Samba network server is visible on all computers - I have not had time yet to do some tests on access and write speed. I have 930 GB shared space on RAID 5 which is in process of being subdivided into separate shares for video, images, music, and so on.\nInstallation was really nice and I was very pleasantly surprised how huge progress did Linux made since 2000 when I last time was really spending some time on it (I was always using Linux as file server and Webserver, but since year 2000 never actually was working in Linux environment). The only minor issue during configuration was that after installing suggested updates (one almost feels like with Windows when Linux box tells you that there newer versions for 200 something packages available), the mouse disappeared. It was there, I could drag and drop, click - but it was invisible. It took less then minute googling to find an answer. As usually in Linux, once you find what is wrong, fixing it is very easy. All I had to do was editing /etc/X11/xorg.conf file (which is of course text file) and adding: Option \"HWCursor\" \"off\" to the Videocard device section.\n---- xorg.conf ----\nSection \"Device\"\nIdentifier \"Videocard0\"\nDriver \"nv\"\nOption \"HWCursor\" \"off\"\nEndSection\n----------------------\nand the cursor automagically reappeared. Hint: do not forget the quotes arounds \"off\" - otherwise X Windows does not start :-).\nSo now I have my NAS and the long part of the work starts. I will have to define shares, assign access rights and the start moving the content to the NAS and cleaning it up in the process. I expect to learn and re-discover a lot in the process - more than I learned until now. Cannot wait ...\n","date":"February 2, 2007","externalUrl":null,"permalink":"/posts/2007-02-02-nas-odyssey-almost-there/","section":"Posts","summary":"As the tittle says, Fedora Core 6 is it. Everything is installed, everything works. The box is very fast, Samba network server is visible on all computers - I have not had time yet to do some tests on access and write speed. I have 930 GB shared space on RAID 5 which is in process of being subdivided into separate shares for video, images, music, and so on.\nInstallation was really nice and I was very pleasantly surprised how huge progress did Linux made since 2000 when I last time was really spending some time on it (I was always using Linux as file server and Webserver, but since year 2000 never actually was working in Linux environment). The only minor issue during configuration was that after installing suggested updates (one almost feels like with Windows when Linux box tells you that there newer versions for 200 something packages available), the mouse disappeared. It was there, I could drag and drop, click - but it was invisible. It took less then minute googling to find an answer. As usually in Linux, once you find what is wrong, fixing it is very easy. All I had to do was editing /etc/X11/xorg.conf file (which is of course text file) and adding: Option \"HWCursor\" \"off\" to the Videocard device section.\n","title":"NAS Odyssey: Almost there","type":"post"},{"content":"Since last week we have switched our corporate emails from our ISP to Google Apps for Domains. This gives everybody very easy way how to access and share the Calendar and Contacts, provides Web interface that really works - as well as capability to access your emails via POP3. So far I am very happy with it and the feedback I have got from other Thinknostickers was positive (or none, which means everything is likely OK).\nThis also created interesting challenge for those of us, who were using GMail for personal emails and GCalendar to plan your life outside of the work. Solution was pretty simple: two browsers and correctly shared calendars.\nThe two browsers are must, because you cannot be logged on into two GMail accounts in one browser at the same time. The implementation was trivial: in addition to my default browser (Firefox, on both platforms), I can finally get some useful mileage out of the \"secondary\" browser (Internet Explorer or Safari). It is kinda funny that the secondary browser is actually native browser for each platform. But I did not mean secondary as something negative. Safari is excellent browser and IE7 is pretty neat too and quite fast - they just happen not to have so many cool plugins as Firefox.\nSo I've decided to keep using Firefox for personal GMail and start using IE7/Safari for gmail dot thinknostic dot com. Sharing calendars it is even more cool. In work account, I have shared my work calendar (named Miro Adamy) with whole team. In addition to that, I am sharing my work calendar with my personal gmail address and the sharing is \"user can change calendar\". With this setting, I am able to see all the events that are planned for my work calendar and compare / overlap it with personal calendar, I can also enter from Firefox events into both. I have also made the sharing the other way: I have allowed my personal calendar to be seen and modified by my work identity. This way I have free selection: either go to my \"personal\" browser and see my personal calendar (with calendars of family members) with my work calendar on top of that - or go to my work browser and see my work calendar (with calendars of my colegauages ) and my personal calendar. This way you can see overlaps between work and personal affairs in either environment - and the \"context\" calendars on top.\nThe only problem now is that the space in my personal calendar seems to be somehow very small and shrining recently. But there is nothing Google can do about this :-(\n","date":"February 1, 2007","externalUrl":null,"permalink":"/posts/2007-02-01-using-multiple-gmailgcalendar-accounts/","section":"Posts","summary":"Since last week we have switched our corporate emails from our ISP to Google Apps for Domains. This gives everybody very easy way how to access and share the Calendar and Contacts, provides Web interface that really works - as well as capability to access your emails via POP3. So far I am very happy with it and the feedback I have got from other Thinknostickers was positive (or none, which means everything is likely OK).\n","title":"Using multiple GMail/GCalendar accounts","type":"post"},{"content":"In order to provide HD Video capabilities and to appease content creators, Microsoft went very far in making sure the Vista is not seen as a tool for content piracy. Did they went too far ? What will be the real cost of this contraversial features ?\nListen (or read) the comments of people that understand the DRM topic better than me and make your own opinion:\n* How and why Windows Vista has incorporated the most pervasive and invasive system for digital rights management ever created, AACS - as MP3 and PDF\n* Interview with Peter Gutmann on Vista DRM - as MP3 and PDF\n* Vista DRM Wrap-Up - as MP3 and PDF\n* Microsoft's response to Peter Guttman and Paul Thurrot on the above\nToo bad that this huge effort that went into killing the opennes of the PC platform (which was the main and only reason for its market dominance, against technologically superior Apple computers) was not spent on something actually useful - for example on the features that were silently dropped from Longhorn (anybody remembers WinFS ?), or making the CLR inside the SQL Server 2005 useful for real life, non-Hello World applications (try to run larger piece of software that works with XML inside the SQL Server and you'll see what I mean).\nAs for my self, I am not keen at all to jump onto Vista train. Yes, it looks nice - but so does OS-X. Yes, WinFX and XAML are interesting - but so is XUL and there is nothing wrong with .NET 2.0. And the XP can run the Framework 3.0 - so what is the big deal ? Eventually, over year or two, Vista will come with new hardware - it is unavoidable. But until that time, I will stay with XP and postpone the upgrade as much as i can. And to be proactive and have Plan B, maybe I'll start to learn Objective C :-)\n","date":"January 31, 2007","externalUrl":null,"permalink":"/posts/2007-01-31-before-you-upgrade-to-vista-you-should-read-this/","section":"Posts","summary":"In order to provide HD Video capabilities and to appease content creators, Microsoft went very far in making sure the Vista is not seen as a tool for content piracy. Did they went too far ? What will be the real cost of this contraversial features ?\nListen (or read) the comments of people that understand the DRM topic better than me and make your own opinion:\n* How and why Windows Vista has incorporated the most pervasive and invasive system for digital rights management ever created, AACS - as MP3 and PDF\n","title":"Before you upgrade to Vista, you should read this","type":"post"},{"content":"As the title says, the Ubuntu is out. Not really because of some technical flaw or missing features (as the FreeNAS, NASLite+ and OpenFiler before), but because of lack of experience and patience on my side. Unlike other distribution which come pre-packed on DVD, Ubuntu installs from a single CD. There are 3 CD variations available: Desktop, which most of the people use and which is likely responsible for Ubuntu fame, Server and Alternative. I did not want to go with desktop - for obvious reasons, so I started to install Server. It installed OK, except it did not offered any option to create RAID. Technically, I still had the RAID created from experiments with OpenFiler, but as I was not sure in which state did I left it, I wanted to recreate it.\nThe server installation, unfortunately does not install any GUI and all operations are performed from command line. I dare to administer Apache and Samba via command line, but meddling with file system operations made me feel really uncomfortable. I tried installed webmin (using apt-get) but it did not succeed at the first attempt and gave up afterwards. Ubuntu seems to cover well two sides of the Linux experience scale: beginers (ex-Windows users) and experienced Linux guys. For somebody who needs more than simple desktop but does not really want to go to deep internals, it does not provide very much. Maybe the alternative install would do - but I gave up, time to move ahead.\nI decided to try Fedora first. There seems to be lot of information available (such as books on Safari Online) and I know few people that use Fedora and may be a good source of information if I get stuck.\nI've encountered few issues during Fedora setup. First - there seems to be a bug in Anaconda installer: as soon as you try to select additional RPM repositories, it crashes and you can start from beginning - as nothing was saved yet. Lesson learned: do not do that. The other problem I've seen had nothing to do with Linux: my setup kept freezing and crashing at first. I figured out that there likely was an IRQ conflict between USB and RAID - after I disabled RAID on BIOS, it disappeared. Right now, I have selected the packages and the installer runs ...\nPut alltogether: it was great lerning experience so far and much more complicated that I have expected, but quite fun. And that is only beginning - I am pretty sure I'll learn much more cool stuff in the process of managing my new (still not existing) NAS. I have to hurry up, because the all NSLU2 died and the family archive of images and videos is inaccessible on USB drive formatted as ext3 filesystem ...\n","date":"January 31, 2007","externalUrl":null,"permalink":"/posts/2007-01-31-nas-odyssey-fedora-core/","section":"Posts","summary":"As the title says, the Ubuntu is out. Not really because of some technical flaw or missing features (as the FreeNAS, NASLite+ and OpenFiler before), but because of lack of experience and patience on my side. Unlike other distribution which come pre-packed on DVD, Ubuntu installs from a single CD. There are 3 CD variations available: Desktop, which most of the people use and which is likely responsible for Ubuntu fame, Server and Alternative. I did not want to go with desktop - for obvious reasons, so I started to install Server. It installed OK, except it did not offered any option to create RAID. Technically, I still had the RAID created from experiments with OpenFiler, but as I was not sure in which state did I left it, I wanted to recreate it.\n","title":"NAS Odyssey: Fedora Core","type":"post"},{"content":"My love affair with OpenFiler did not last very long. After installation finished, I started browser, pointed to URL I was told by the installer and started to configure. The Web admin was OK, nothing really exciting, but functional. The bad surprise came when I was trying to define users - in order to define volumes later. And here came the screen saying:\nPlease note that Openfiler needs a central directory service\non the network to function, which it and the client machines can see and use.\nYou cannot use local users and groups with Openfiler.\nOtherwise there is no means to implement authorisation\nas one machine's information about users and groups can differ from another's.\nYou can configure the directory service below.\nIt offered me either use LDAP server or point to Windows domain controller. Well - too bad. I certainly have no intention to install and run LDAP for the four users I have at home, and if I ever will have a Windows server, it will not be an add-on to Linux NAS but a replacement for failed attempt to install Linux NAS (my Plan B). And it certainly will be neither Domain controller nor Active Directory server - as I am not a big fan of either approach. Anyway - I cannot use OpenFiler, the next step is to try out real Linux distributions, in order Ubuntu, Fedora and OpenSuse.\nSo I started to getting the installation images ready. I have downloaded the DVD ISO for Fedora and OpenSuse and CD ISO for Ubuntu. While doing that I practically tried out Bittorrent for the first time. Stop laughing - I was really not using Torents until now. Somehow the fashion of downloading of MP3's and movies from peer-2-peer networks avoided by me. The client I used was Azureus - beautiful opensource piece of software written in Java. Maybe, with the current superfast dual-core machines and 1-2 GB RAM as minimum, time has come to re-evaluate the idea of thick client written in Java ?\nBut back to the installs. First series of downloads did not work. Neither of them. Probably because I have downloaded the x86_64 versions. Each of the systems crashed in various stages of loading Linux kernel - so I assume, there must be some issue with HCL of my configuration. I have read few weeks ago somewhere on the Net that \"... trying to go with 64 bits is begging for troubles ... \" - but did not know how it is.\nSo I am back to running torrents - the i386 versions of Ubuntu Server 6.10 CD is already downloaded and the other two DVD's are coming. It will take few hours. We will see if the problems were indeed caused by the x86_64 versions.\nLet's start with Ubuntu ....\nTo be continued\n","date":"January 30, 2007","externalUrl":null,"permalink":"/posts/2007-01-30-nas-odyssey-openfiler-is-out-lets-try-ubuntu/","section":"Posts","summary":"My love affair with OpenFiler did not last very long. After installation finished, I started browser, pointed to URL I was told by the installer and started to configure. The Web admin was OK, nothing really exciting, but functional. The bad surprise came when I was trying to define users - in order to define volumes later. And here came the screen saying:\nPlease note that Openfiler needs a central directory service\non the network to function, which it and the client machines can see and use.\nYou cannot use local users and groups with Openfiler.\nOtherwise there is no means to implement authorisation\nas one machine's information about users and groups can differ from another's.\nYou can configure the directory service below.\n","title":"NAS Odyssey: OpenFiler is out, let's try Ubuntu","type":"post"},{"content":"After spending most Saturday and Sunday fixing, coding and logging bugs, I finally got to moving ahead. Very likely it is about time, because the NSLU2 keeps producing strange sounds\nThe box has now additional IDE 160 GB IDE disk, which will hold Linux installation as well as \"temp\" share, which will not be RAID-ed. Sort of staging area for the stuff in flux.\nAfter contemplating for a while which distribution to use - and generally, whether to build more generic Linux server with Samba or more appliance-type box, I went on with trying OpenFiler first. The truth is that my old Linux box did 99% of his services as Samba fileserver and very little as Web server / Java application server. Most of the fancy GUI applications were barely used - including pretty loaded Gnome and KDE installation (one can never decide which one is actually better). So why to repeat same mistake twice ?\nNevertheless, I have created a shortlist of distributions and prepared the media. Here is the shortlist:\na) Ubuntu\nb) Fedora Core\nc) Open Suse\nI have no real rational reason why exactly these 3 distros and why this order - decision was partially based on reviews from Net and partially on personal recommendations.\nInstallation of OpenFile (still running) was very straightforward. Of course, you have to select manual partitioning, not automatic if you want to create RAID. I have created 4 partitions on /dev/hda - /boot, /, swap and /var - occupying the rest of the system - as ext3. The SATA disk got created one large partition each, formated as Software Raid. The actual raid - /dev/md0 - was created right in disk partitioning tool. The only uncertainty was the number after 'Number of spares'. I was not sure what it means \"spare\" - but then decided that it should be the number of spare partitions actually not participating in the RAID, just available, in case something would fail. I have left the default value 0 and moved on.\nThe created RAID was as expected, over 915 GB large (4x305 GB disks in RAID5 = 3x305+parity). After that, the installer requires to set time zone, IP address and hostname and starts formatting the partitions, which will take long, long long time - it is running now for over an hour ...\nFew good links to the topic: Linux SATA RAID FAQ, explanation Why software RAID,\nTo be continued\n","date":"January 29, 2007","externalUrl":null,"permalink":"/posts/2007-01-29-joys-of-the-opensource-nas-part-2-openfiler/","section":"Posts","summary":"After spending most Saturday and Sunday fixing, coding and logging bugs, I finally got to moving ahead. Very likely it is about time, because the NSLU2 keeps producing strange sounds\nThe box has now additional IDE 160 GB IDE disk, which will hold Linux installation as well as \"temp\" share, which will not be RAID-ed. Sort of staging area for the stuff in flux.\nAfter contemplating for a while which distribution to use - and generally, whether to build more generic Linux server with Samba or more appliance-type box, I went on with trying OpenFiler first. The truth is that my old Linux box did 99% of his services as Samba fileserver and very little as Web server / Java application server. Most of the fancy GUI applications were barely used - including pretty loaded Gnome and KDE installation (one can never decide which one is actually better). So why to repeat same mistake twice ?\n","title":"Joys of the Opensource NAS - Part 2: OpenFiler","type":"post"},{"content":"Even Dalai-lama is using it. See the proof - http://flickr.com/photos/timsimpson/255420579/\nNote for Gabo - it looks like Macbook Pro :-).\n","date":"January 28, 2007","externalUrl":null,"permalink":"/posts/2007-01-28-mac-is-the-way-to-enlightenment/","section":"Posts","summary":"Even Dalai-lama is using it. See the proof - http://flickr.com/photos/timsimpson/255420579/\nNote for Gabo - it looks like Macbook Pro :-).\n","title":"Mac is the way to enlightenment","type":"post"},{"content":"I have been living with my Sony eReader for almost a month now and managed to read about two full books. If not the time crush in biometric project, I would have probably read much more than just two books - nevertheless, I do have some real life experience with the device.\nFirst - the claimed battery life of 7500 page turns is BS. I have observed real battery life about 15-20 hours, so unless you manage to turn about 500 pages per hour, it just does not add up. I have observed that battery was good for about 1 full book (about 400 letter pages, or about 900 \"small\" pages on reader), read over 2 weeks period, the battery dropped from full charge to one segment. It is possible that it depends on how reading style - if you are turning pages and reading continuously, it lasts longer. Browsing through books seems to consume considerable energy. I think that 15-20 hours reading time is more than enough - it will keep you busy on flight to Australia :-). Certainly huge improvement against PDA based readers, where the battery life is 4-5 hours max. My 2 years old PocketPC is now down to about 3.5 hrs. I am still using it because a) I have lots of books in PalmDoc and CHM formats and b) I like to read in bed ...\nI have looked at the content of the SD card as it is in file system. The Reader does not seem to do any conversion for the files involved - the copied PDF and RTF files are binary equal to the original files. The structure of the SD card is:\n\\Sony Reader\\\n\\Sony Reader\\books\n\\Sony Reader\\database\nThe books folder contains all files copied into SD. The database contains single XML file cache.xml, which holds directory of the books. I do not know yet whether the file indeed a directory or what it says - a cache. Simple experiment to do is to copy few files and test of Reader will find them and updates the cache. The book metadata has following format as:\n\u0026lt;text author=\"AUTHOR NAME\" page=\"0\" part=\"0\" scale=\"0\" sourceid=\"37\" id=\"269\"\u0026gt;\ndate=\"Sat, 30 Dec 2006 22:42:12 GMT\" mime=\"text/plain\"\npath=\"Sony Reader/books/FILENAME.txt\" size=\"339623\"\ntitle=\"BOOK TITLE\"\u0026gt;\n\u0026lt;layouts\u0026gt;\n\u0026lt;layout part=\"0\" scale=\"0\"\u0026gt;\n...\nI am not sure how the one or more encoded binary chunks - layouts (for various scales) work. The encoded jpeg -thumbnail is on the hand pretty obvious.\nThe source of the information appearing in the metadata depends on the source format. For PDF and RTF files, Connect software seems to access the document properties, for TXT files I did not figure it out yet.\nSo to get good content on the Reader requires\na) get the metadata right and\nb) convert the content into best readable format.\nWhich is, unfortunately the proprietary format BBeB. The readibility of the BBeB is far the best, it offer nicer text, better sizing and overall much better reading experience. The good news is, that it is possible to create content in this format and first few tools are appearing on the net. I will try them out and post the results here as soon as I am done. Until that time, you can download free ebooks (Project Gutenberg and others) on Manybooks.net directly in the eReader format.\nThis site is very good source of information on the eReader and things around it.\n","date":"January 27, 2007","externalUrl":null,"permalink":"/posts/2007-01-27-more-on-sony-reader/","section":"Posts","summary":"I have been living with my Sony eReader for almost a month now and managed to read about two full books. If not the time crush in biometric project, I would have probably read much more than just two books - nevertheless, I do have some real life experience with the device.\nFirst - the claimed battery life of 7500 page turns is BS. I have observed real battery life about 15-20 hours, so unless you manage to turn about 500 pages per hour, it just does not add up. I have observed that battery was good for about 1 full book (about 400 letter pages, or about 900 \"small\" pages on reader), read over 2 weeks period, the battery dropped from full charge to one segment. It is possible that it depends on how reading style - if you are turning pages and reading continuously, it lasts longer. Browsing through books seems to consume considerable energy. I think that 15-20 hours reading time is more than enough - it will keep you busy on flight to Australia :-). Certainly huge improvement against PDA based readers, where the battery life is 4-5 hours max. My 2 years old PocketPC is now down to about 3.5 hrs. I am still using it because a) I have lots of books in PalmDoc and CHM formats and b) I like to read in bed ...\n","title":"More on Sony Reader","type":"post"},{"content":"Today's extension provides easy way how to access and add content to great free service from Google - Google Notebook. I am using it for over 3 months now and find it very useful and easy to use.\nAs other Google product, Google Notebooks is simple, has clean interface and not too many features. The extension available from Google tools for Firefox make using it even easier. It allows you to create notes - Web clippings, by selecting part of Web page and choosing \"Note this (Google Notebook)\" from context menu, selection is added to currently active notebook.\nThe extension also allows to work with your notebooks. It occupies right bottom part of the Firefox status bar:\nafter opening it by clicking on it, you can either keep the notebook opened in minimalistic one line version:\nor mini-window (by using the first of the three buttons on the right in notebook header). Here is is the mini-window view:\nThe last button closes the notebook and the second button opens (in new tab) full screen view of the notebook:\nOn the right sight, you can see list of existing notebooks. Every notebook can contain many clippings. Each clip can be either expanded to show full content or collapsed to display two line summary. You can rearrange order of the notes in notebook by drag and drop (which is much easier when they are collapsed). You can organize the notes within the notebook into sections. The action menu on the right allows to create/delete section, add, rename or delete notebook. One of the notebook is always active and all your clips will end up inside it. If you want to keep separate notebooks for different areas, you can use the button next to Notebook title to quickly change active notebook:\nGoogle notebook is providing very similar functionality as the Scrapbook extension - but it keeps all clippings on-line, which is both pro and cons. If you are using single computer, Scrapbook has an advantage of keeping saved pages available even when you are offline. It also gives you more options for managing clips: merge, import/export. GN allows only rearrange content, simple edit and print.\nAs many other Google tools, Google Notebook does one thing and does it well. Saving Web clip can hardly be easier. If you do not need import/export and want to have access to your clips from any place, give it a try.\n","date":"January 26, 2007","externalUrl":null,"permalink":"/posts/2007-01-26-feotd-google-notebook/","section":"Posts","summary":"Today's extension provides easy way how to access and add content to great free service from Google - Google Notebook. I am using it for over 3 months now and find it very useful and easy to use.\nAs other Google product, Google Notebooks is simple, has clean interface and not too many features. The extension available from Google tools for Firefox make using it even easier. It allows you to create notes - Web clippings, by selecting part of Web page and choosing \"Note this (Google Notebook)\" from context menu, selection is added to currently active notebook.\n","title":"FEOTD: Google Notebook","type":"post"},{"content":"","date":"January 26, 2007","externalUrl":null,"permalink":"/tags/firefox/","section":"Tags","summary":"","title":"Firefox","type":"tags"},{"content":"I have started to listen the Security Now! podcasts from the very beginning - sometimes in summer 2005. Unlike some news-and-rumours podcasts that sound kind of weird if you listen them month later, this one did not loose a bit of it's freshness. Even listening the story of Sony Rootkit discovery again was very entertaining. I am now at first \"mod-4\" Q\u0026amp;A podcast, Number 16.\nEvery time I listen to Steve Gibson, one of two things happens. Either I learn something new, or I discover new, better way how to explain something I knew about in a very nice, accessible way. Steve's handling of differences between WEP and WPA, explanation why MAC address filtering gives no security and his VPN coverage was an excellent example of the later.\nOn the NAS building front: I have decided to go with 4 SATA + 1 IDE configuration and keep all 4 SATA disks fully RAID-5-ed. I have not yet decided which distribution I will put on. Probably will start with OpenFiler, but Ubuntu looks pretty good too and deservers a try. Btw, Peter is trying to convince me to use BIOS RAID and build a Windows 2003 server - but that is still a Plan B. If time permits, will move the yardstick on Saturday night. It may be delayed, because the biometric security project is quickly approaching the release phase and - as usual - time will be a precious resource.\n","date":"January 25, 2007","externalUrl":null,"permalink":"/posts/2007-01-25-evergreen-security-now/","section":"Posts","summary":"I have started to listen the Security Now! podcasts from the very beginning - sometimes in summer 2005. Unlike some news-and-rumours podcasts that sound kind of weird if you listen them month later, this one did not loose a bit of it's freshness. Even listening the story of Sony Rootkit discovery again was very entertaining. I am now at first \"mod-4\" Q\u0026A podcast, Number 16.\nEvery time I listen to Steve Gibson, one of two things happens. Either I learn something new, or I discover new, better way how to explain something I knew about in a very nice, accessible way. Steve's handling of differences between WEP and WPA, explanation why MAC address filtering gives no security and his VPN coverage was an excellent example of the later.\n","title":"Evergreen Security Now!","type":"post"},{"content":"Webbit is like timbit - it comes in 12, 20 or 40 pack, contains many small pieces of different taste and color, is generally unhealthy but good, can be addictive and is nice addition to your morning \"extra large, double cream\" from Tim Hortons. Unlike from timbits, from webbits you will not get fat, only distracted. Enjoy !\nThe Quizstop allows you to select how fast are you reflexes with the mouse. Something for those with competitive gene among us (I mean you Igor, of course ;-).\nDifferent kind of test is on http://jakemandell.com/tonedeaf/ It plays you two tone sequences and your job is to decide whether they are the same or not. Flash required.\nFunny geek quotes. Free ebook on Programming in Ruby. Keyboard shortcuts for Mozilla Firefox.Timeline of Linux distros. 50 beautiful CSS designs. Very interesting blog idea - view from your window. Some views would be good as wallpaper, but if you need more variety, try the list of sites with nice wallpapers. Free ebook on Blender.\nFew interesting blogs: on data/text mining, visualization and gis, on future of the books, visual communication, and even blog almost without words. Blog about programming in Cocoa environment on OS-X. Another rumor site on all things Apple. If you like better DotNET, look here and here.\nInteresting on-line test data generator.\nFor those of us who have daughters, here is something they (== the girls) may like.\n","date":"January 23, 2007","externalUrl":null,"permalink":"/posts/2007-01-23-webbits-2007-01/","section":"Posts","summary":"Webbit is like timbit - it comes in 12, 20 or 40 pack, contains many small pieces of different taste and color, is generally unhealthy but good, can be addictive and is nice addition to your morning \"extra large, double cream\" from Tim Hortons. Unlike from timbits, from webbits you will not get fat, only distracted. Enjoy !\nThe Quizstop allows you to select how fast are you reflexes with the mouse. Something for those with competitive gene among us (I mean you Igor, of course ;-).\n","title":"Webbits - 2007-01","type":"post"},{"content":" Thanks to Lifehacker I have discovered this extension which add missing piece of GMail functionality: This very simple extension allows you to enter multiple sets of text (such as e-mail signatures) and paste them into forms simply by right-clicking.\nWhy is this such a big deal ? I am using GMail for both my personal and work stuff. To make sure my work related email appear as coming from company email address, I set the proper From address when composing an email. GMail can be configured to stay with the recipient address when replying. The only problem is signature. In private emails, I want to have link to the blog, in work emails, to company site. And GMail offers only one signature. With this extension, I do not use any signature from GMail, just simply insert correct one from the Clippings buffer.\nThere are other solutions Gmail multiple signatures Greasemonkey script but they are quite heavyweight for simple problem (which was main reason I did not try them out).\nGet it at usual place.\n","date":"January 22, 2007","externalUrl":null,"permalink":"/posts/2007-01-22-feotd-clipping-gmails-best-friend/","section":"Posts","summary":" Thanks to Lifehacker I have discovered this extension which add missing piece of GMail functionality: This very simple extension allows you to enter multiple sets of text (such as e-mail signatures) and paste them into forms simply by right-clicking.\nWhy is this such a big deal ? I am using GMail for both my personal and work stuff. To make sure my work related email appear as coming from company email address, I set the proper From address when composing an email. GMail can be configured to stay with the recipient address when replying. The only problem is signature. In private emails, I want to have link to the blog, in work emails, to company site. And GMail offers only one signature. With this extension, I do not use any signature from GMail, just simply insert correct one from the Clippings buffer.\n","title":"FEOTD: Clippings - GMail's best friend","type":"post"},{"content":"Well, as it looks like, I was prematurely ecstatic about the new open source based NAS server. While the hardware works great, I had not much luck so far with setting up the software on top of that.\nMy original idea was to use FreeNAS, let it boot and install into USB drive and use all 4 SATA disks in RAID 5 set up by BIOS. It did not work. FreeNAS does not see the RAID5 volume created by BIOS and keeps referring to 4 separate SATA drives. So does Openfiles and few other distributions. After the USB key was initialized, the system did not boot and stopped with error message 'No Ufs'.\nSome research later, I found out that the drivers for the chipset needs to be installed in order the hardware RAID to be recognized. In the process of searching I've learned more about RAID's than I ever wanted to know :-) and found out that the hardware RAID I have is in reality half software solution and without loaded drivers and help from OS will not work. Not much surprise, one cannot expect from $110 mainboard to be everything for everybody.\nI did few experiments with using 4 SATA disks as separate volumes and set up software RAID 5 in FreeNAS. It worked OK, so as long as you resolve the problem with booting, this almost would be a workable solution. For now, while I am experimenting with the system, it is booting from additional 40GB IDE drive. The \"almost\" part is bad surprise in FreeNAS capabilities. It allows you to create users and even groups (dunno why), but the access control is all or nothing. For volume, you can set level of authentication required - anonymous, local user or domain, but you cannot define any restrictions on access. For example, you cannot have read only access. This makes FreeNAS completely unsuitable for what I need - I must be able to export read only shares. To do that, I will very likely have to use normal Linux distribution (preferably some with Web based admin interface), and properly configure servers and security. It should not be terribly hard, the trouble is that I know too little about all that Linux-hardisks stuff. On the other hand, it is a great learning opportunity.\nAs for RAID, there are two possible ways ahead: option one is to get the BIOS RAID working. This would require to find the proper drivers for the Linux kernel version I will be using and learn how to add driver during Linux installation. The other is use software RAID provided by several distributions - e.g. by Openfiler. It may not be as bad as it sounds, because using software RAID inside Linux distributions is exactly what cheaper NAS devices are doing. It does not even have to mean that the performance will be much worse: the main reason these lower end NAS devices are slow in RAID configuration is not enough CPU power and enough memory - typically they have some ARM processor and 256 MB RAM. On my box, I have full Athlon 64 and 1 GB RAM, which is way more powerful.\nThe tricky part is how do divide the 4 disks into partitions so that I can place /boot and swap somewhere and keep the root partition on RAID-ed disk. It can be tricky, because the partitions that participate in RAID should have same size and you still need to place the /boot swap and the root partition somewhere. Because they are so important, it would be great if they could sit on RAID, but of course it is a chicken-egg problem, because the RAID is created after Linux boots.\nI see two options (and you guys who actually do understand this stuff, feel free to correct me if I am completely wrong):\na) keep the IDE drive (which will hold the MBR, /boot, swap and root file system) for boot and Linux installation and create one partition per SATA disk, all combined into large RAID-5. This way, all space on SATA drives is utilized. The IDE is single point of failure, but if it fails, it should be quite easy to boot some LiveCD and reconfigure the access to the data, because the sofware RAID support is built into new kernels and should work the same, regardless of distribution. The most of the IDE disk space will be available - the Linux distribution will comfortably fit into 2-4 GB, and the rest of 80 GB (the smallest disk you can buy) can be exported as quick, no-RAID, working disk space (staging area or temp).\nb) Partition the SATA disks so that the boot, swap and system partition are on the first disk. The size of the rest of disk wil be determining the primary RAID volume size. The equivalent sized partitions to the system size on the other disks are combined into second RAID5 volume. For example\nhda1 - 100 MB = boot, hda2 - 2 GB = swap, hda3 - 4 GB = system, hda4 - 3xx GB = space for RAID 5\nhdb1 - 100 MB = (copy of boot), hdb2 - 6 GB = space for vol2 RAID, hdb3 - 3xx GB = space for RAID 5\nhdc1 - 100 MB = (copy of boot), hdc2 - 6 GB = space for vol2 RAID, hdc3 - 3xx GB = space for RAID 5\nhdd1 - 100 MB = (copy of boot), hdd2 - 6 GB = space for vol2 RAID, hdd3 - 3xx GB = space for RAID 5\nAfter that, there will be two RAID5 volumes: one created from hda4, hdb3, hdc3 and hdd3 - which have all same capacity and one created from hdb2, hdc2 and hdd2. The capacities of the volumes will be 3 x 3xx GB (about 900 GB) for big one and about 12 GB for the smaller one. If any of the disks hdb, hdc and hdd fails, nothing happens and after replacement data will be restored. If disk hda fails, in order to restore, the system must be started from LiveCD, reinstalled on hda (with exact partitions and RAID table) and after booting the data will be restored. Kind of complicated but maybe doable.\nThere is always plan B, of course: stay with BIOS RAID and use Windows 2003. It would have exactly same issues with drivers as Linux had, but I know how to install this one (as I have done it when we were setting up the development lab). The machine is powerful enough to run it. What would be nice, is that both OS and data would sit on RAID-ed volume. What I do not like on the Windows idea is the necessity of using GUI to do anything - the Remote Desktop is pretty much only practical way how to administer the system. And I would not learn much new either, I think ...\nYep, more thinking and planning required. I will shelve the RAID project until next weekend. I have mixed feelings about all this. On one hand, it is great to be discovering new things and learning, but it takes so much time: after Yan built the box, we have tried to get it working until 3AM ... Why things cannot \"just work\" as in Mac world ? If budget would not be problem, here is perfect RAID solution :-).\n","date":"January 21, 2007","externalUrl":null,"permalink":"/posts/2007-01-21-the-joys-of-open-source-nas/","section":"Posts","summary":"Well, as it looks like, I was prematurely ecstatic about the new open source based NAS server. While the hardware works great, I had not much luck so far with setting up the software on top of that.\nMy original idea was to use FreeNAS, let it boot and install into USB drive and use all 4 SATA disks in RAID 5 set up by BIOS. It did not work. FreeNAS does not see the RAID5 volume created by BIOS and keeps referring to 4 separate SATA drives. So does Openfiles and few other distributions. After the USB key was initialized, the system did not boot and stopped with error message 'No Ufs'.\n","title":"The joys of open source NAS","type":"post"},{"content":"If you have digital camera or digital camcorder, you probably have a problem where to store the pictures and video so that they are readily available for viewing and protected against loss caused by hardware failure. How much storage you need depends on how many and how large pictures do you take and how heavy camcorder user you are. In my case, I have switched to shooting RAW on my D70, doing about 2000-4000 shots a year and the camcorder produces about 4-5 GB unprocessed video per hour of recording. After adding some free capacity for the document archives, some MP3 files, anything smaller than 500 GB will be probably too small. To have some space, I decided I better go for 1 Terrabyte of space.\nThe main advantage of the local disk storage is speed. Regardless how fast your Internet connection is, it is nothing like 1 GB Ethernet, when it comes to to speedy access to your files. You would of course get most speed if the data were stored on local disks of the machine which uses them, but who uses only one machine :-). To separate data storage into dedicated box offers easier sharing and freedom to reinstall OS on the workstation without impacting data availability. Therefore, I want NAS.\nAnother important feature of the local storage is safety. To protect yourself against data loss, you want to do at minimum RAID storage - likely RAID-5. I was avoding RAID for some time - and as result ended up with many USB disks laying around, lots of cables, power adapters and very complicated cascade backup process, which need to be simplified.\nThe basic question about NAS is to build or to buy. Ideally, I would like to have an appliance, not another computer. There is interesting site on the Net - Small Network Builders which offers lot of information about commercial NAS solutions available. Unfortunately, those devices which were in my desired price range (~ $900 to $1100) for TB storage (like Buffalo Home Server), had serious issues either with read/write performance which was at the level of 100 MB network speed on 1GB LAN - or some multi platform compatibility problems. Another potential problem with some NAS boxes was noise. Running four high-performance hard disk drives inside small enclosure requires good cooling and often makes the NAS noisiest part of your office. My goal is to lower the noise, not increase it. An example of NAS with good performance is the Thecus N5200 - but you have to accept the noise. A system that promises quiet operation was Synology CS-406, but in both cases the enclosure (without disks) price tag was in the range $700-$900. If you assume price of the 5 disks about $600-$700, it is impossible to build 1TB in assumed budget.\nAll commercial NAS devices are computer running usually Linux or BSD Unix with Web based user interface for disk management. The speed of the box is determined (except speed of the disks) by the NIC adapter speed, CPU speed (and amount of RAM) and the overhead of the used OS. Disadvantage of appliance NAS is little control about these and about features supported. With building custom appliance, you have full control and for $800 you can build very decent computer these days.\nI have decided to go with larger case - to allow more space around hard drives, better cooling and quieter fans. I asked Yan to recommend really good mainboard with fast enough CPU - but not too fast to need lots of noisy cooling and enough RAM to have space for buffers. Here is configuration I have ended up with - purchased from my favorite hardware supplier:\n- AMD 64 3500+ AM2 Processor\n- Asus M2NPV-VM AM2 Nf430 mATX MB (Raid5/GbE/Gf6150/VGA/DVI-D)\n- 1GB PC2-5300 DDR2 Memory\n- Lite-On LH-18A1P-185 DVD-RW 18x18\n- Antec Atlas Server Case w/True 500w Power Supply\n- 2xSilenX 92mm 14dBA 2000rpm 36cfm Case Fan\nAlltogether the price for enclosure was $546. If you add five 320 GB SATAII Seagate HDD, 16MB you will end up with 1.2 TB NAS (900 GB after RAID) which is (hopefully) more powerful, quiter and at least 300-400 cheaper than the pre-built alternatives. The machine which does only fileserver is about 3-4 times faster than my current desktop from early 2002 (which did cost about 2.5K$ at that time). Oh boy ...\nTechnically I did not need buy 5 hard drives for RAID-5, only 4. I just picked up one spare to make sure that when it comes to replacement, I have it available. I believe that having same disks has value and if the increase in HDD capacities will continue with current speed, the 320 GB disks may be unavailable soon.\nAs for software, I have not decided yet. The best candidate is the FreeNAS. It is not Linux based, but Free BSD. I have no problem with that, quite the opposite - thanks to Macbook, I have very good relationship with FreeBSD Unix now :-).\nThe machine is completed and running in my office now. It is amazingly quiet - very deep below the level of noise of the other computers. I have not installed OS yet, only booted FreeNAS from the CD. Time to read FreeNAS installation guide I guess.\nWill be continued\n","date":"January 20, 2007","externalUrl":null,"permalink":"/posts/2007-01-20-dealing-with-digital-mess-local-offline-file-storage/","section":"Posts","summary":"If you have digital camera or digital camcorder, you probably have a problem where to store the pictures and video so that they are readily available for viewing and protected against loss caused by hardware failure. How much storage you need depends on how many and how large pictures do you take and how heavy camcorder user you are. In my case, I have switched to shooting RAW on my D70, doing about 2000-4000 shots a year and the camcorder produces about 4-5 GB unprocessed video per hour of recording. After adding some free capacity for the document archives, some MP3 files, anything smaller than 500 GB will be probably too small. To have some space, I decided I better go for 1 Terrabyte of space.\n","title":"Dealing with digital mess: Local (offline) File Storage","type":"post"},{"content":"Since over 1 month I am using Web based tools for calendar, email, task management, bookmark management and note taking. One problem that these tools have is that as soon as your connection goes down, you are done. Game over. Few days ago I have discovered Scrybe, a tool which maybe can address this problem. Unfortunately, I cannot tell from my own experience, because the system is in private Beta and does allow you to register. But if you can believe the sneak peek video (linked from the site), it should combine calendar which is even better than Google Calendar, task manager and note taking program that would make Google Notes look like second class citizen.\nAnd not only every of these program seems to look and work better as the current \"best of the class\", it claims that you can switch the browser (Firefox or IE) to Working Offline mode and keep on using the program, with seamless data resynchronization after the connectivity is restored. It should also nicely synchronize with mobile devices and allows transfer information to and from Office documents via simple copy and paste - without messing up the formatting.\nVery nice feature is also \"paper synchronization\" - printing out fold-able calendar, todo list etc - very similar to PocketMod idea, but with current content. It also should give you very nice way how to turn your notes - Web clippings - into presentable documents. I would love to give it a test ride, if I could.\nIt almost sounds too good to be true. If it is really true what the video shows - Google or Yahoo, please please please buy this company and get the product out to the masses :-)\n","date":"January 19, 2007","externalUrl":null,"permalink":"/posts/2007-01-19-too-good-to-be-true/","section":"Posts","summary":"Since over 1 month I am using Web based tools for calendar, email, task management, bookmark management and note taking. One problem that these tools have is that as soon as your connection goes down, you are done. Game over. Few days ago I have discovered Scrybe, a tool which maybe can address this problem. Unfortunately, I cannot tell from my own experience, because the system is in private Beta and does allow you to register. But if you can believe the sneak peek video (linked from the site), it should combine calendar which is even better than Google Calendar, task manager and note taking program that would make Google Notes look like second class citizen.\n","title":"Too good to be true ?","type":"post"},{"content":"For Jack, Manju and Michel: here is the poem we talked about.\nEye have a spelling chequer\nIt came with my pea sea\nIt plainly marques four my revue\nMiss steaks eye kin knot sea.\nEye strike a key and type a word\nAnd weight four it two say\nWeather eye am wrong oar write\nIt shows me strait a weigh.\nAs soon as a mist ache is maid\nIt nose bee fore two long\nAnd eye can put the error rite\nIts rare lea ever wrong.\nEye have run this poem threw it\nI am shore your pleased two no\nIts letter perfect awl the weigh\nMy chequer tolled me sew.\nAs seen on gopher://seanm.ca/00/stuff/spell-checker.txt\n","date":"January 17, 2007","externalUrl":null,"permalink":"/posts/2007-01-17-improve-your-english-use-spellchecking/","section":"Posts","summary":"For Jack, Manju and Michel: here is the poem we talked about.\nEye have a spelling chequer\nIt came with my pea sea\nIt plainly marques four my revue\nMiss steaks eye kin knot sea.\nEye strike a key and type a word\nAnd weight four it two say\nWeather eye am wrong oar write\nIt shows me strait a weigh.\nAs soon as a mist ache is maid\nIt nose bee fore two long\nAnd eye can put the error rite\nIts rare lea ever wrong.\n","title":"Improve your English, use spellchecking !","type":"post"},{"content":"If it ever happens to you that you need to restart old computer which you have not logged on for 2-3 months and you find out you have no clue what the password could be, do not panick. Exactly this happened to me yesterday. Fortunately I have remembered reading something on lifehacker few days ago about bootable CD which contains live Linux distribution with password cracking open source software Ophcrack. It runs from CD only, does not touch your file system, only loads local SAM and tries cracking the hashes. And boy, it works !\nI downloaded and burned the ISO and rebooted the old Windows box. It had the password in less than 8 minutes. Then, just out of curiosity, I booted up my Windows notebook which I use for one of the projects with the crack CD. On this notebook I use fairly reasonable password, 9 characters, combination of uppercase, lowercase and numbers, which is not valid word in any language (to avoid dictionary attacks). About two minutes after boot and start the notebook fan started to go full speed, a clear signal that the 3.2 GHz Pentium 4 HT works like crazy. The password was cracked in 18 minutes.\nThis thing is pretty scary, if you consider all possibilities.\n","date":"January 16, 2007","externalUrl":null,"permalink":"/posts/2007-01-16-how-to-recover-lost-win-xp-password/","section":"Posts","summary":"If it ever happens to you that you need to restart old computer which you have not logged on for 2-3 months and you find out you have no clue what the password could be, do not panick. Exactly this happened to me yesterday. Fortunately I have remembered reading something on lifehacker few days ago about bootable CD which contains live Linux distribution with password cracking open source software Ophcrack. It runs from CD only, does not touch your file system, only loads local SAM and tries cracking the hashes. And boy, it works !\n","title":"How to recover lost Win XP password","type":"post"},{"content":"With great horror I have discovered that from my 80 GB hardrive in Macbook already over 76 GB was full. Mostly because of the hidden activity of iTunes and silent downloading of new podcast episodes. Especially video podcasts - such as Mac break - are disk heavy, since they are produced in HD - and as result, look remarkably beautiful on the screen.\nWhile cleaning up, I have decided to burn few of my very favorite podcasts to the MP3 CD and keep it in the car. Doing that is really easy in iTunes - all you have to do is to select MP3 CD in Preferences -\u0026gt; Advanced -\u0026gt; Burning, create a playlist that will contain all MP3's you want to burn, control-click it and select Burn. So far so good. There are some situations when yu want to have more control over the process: for example you want to put the files to subfolders or need to adjust / cleanup the names of files before burning.\nWhen I wanted to burn all episodes of Security Now!, I found out that files are having very different naming conventions: from super-brief 'SN-018.mp3' to 'Security Now 44: Your Questions, Steve's Answers - sponsored by Astaro Corp..mp3'. I did not like that and specially did not like two dots and special characters in name, so I decided to clean up the file names and burn CD manually. Because iTunes keeps separate database of the music files, I did not want to mess with the files under its control directly and decided to copy them elsewhere. It is easy to find out that files are in /Users/USERNAME/Music/iTunes/iTunes Music/Podcasts/PODCAST-NAME/ as plain MP3 files. Not all of them, though. Only podcasts that were downloaded as podcasts - which in my case were episodes 45 and up, because, for some reason, iTunes did not offer earlier episodes. Later on I have downloaded the episodes 1-44 from Steve Gibson's website and imported them to library, however they ended up being \"music\", not podcasts and were stored according the Album and Artist information from MP3 file. That means all over the place, as some files had 'Leo Laporte with Steve Gibson' as artist, some 'Steve Gibson' and some none. It was easy to collect them all in one playlist, but before manually searching multiple directories, I thought - there must be a better way !\nAnd there indeed is. The answer was Applescript and wonderful site full of iTunes Applescript goodies named Doug's Applescript for iTunes. I found there script 'Alias files to folder' and 'Copy files to folder'. Installation is very easy: you download the .dmg file (disk image) doubleclick it (to mount it) and drag the icons to the arrow - as the image says\nAfter that, you will see in the iTunes menu small script icon.\nSelect all files you want to copy, activate the script, select destination directory - and you are done. The files will be copied where you selected.\nThe site contains lots of very useful scripts. You can find a script which for example, allows converting between file formats in batch, making files bookmarkable. It can join tracks, get a list of music files that are not contained in the iTunes library, colortag the files based on type (lossless, protected, mp3,desktop movie, ipod movie etc), set filename to author-\u0026gt;track name, synchronize the iTunes database with local file folder (fantastic for the external USB drives !), search Wikipedia or Amazon for the album/artist info, find artwork on internet using Google. It can even copy the music from iPod to iTunes (works works with Mac formatted iPods only), automatically generate PDF booklets, find song lyrics, rip directly to iPod, remotely control iTunes on different machine or export playlist into XML format.\nI think I will start seriosly consider looking at this Applescript thing :-)\n","date":"January 15, 2007","externalUrl":null,"permalink":"/posts/2007-01-15-automating-itunes/","section":"Posts","summary":"With great horror I have discovered that from my 80 GB hardrive in Macbook already over 76 GB was full. Mostly because of the hidden activity of iTunes and silent downloading of new podcast episodes. Especially video podcasts - such as Mac break - are disk heavy, since they are produced in HD - and as result, look remarkably beautiful on the screen.\nWhile cleaning up, I have decided to burn few of my very favorite podcasts to the MP3 CD and keep it in the car. Doing that is really easy in iTunes - all you have to do is to select MP3 CD in Preferences -\u003e Advanced -\u003e Burning, create a playlist that will contain all MP3's you want to burn, control-click it and select Burn. So far so good. There are some situations when yu want to have more control over the process: for example you want to put the files to subfolders or need to adjust / cleanup the names of files before burning.\n","title":"Automating iTunes","type":"post"},{"content":"Chocolate Chip Cookies Recipe\n1.) 532.35 cm3 gluten\n2.) 4.9 cm3 NaHCO3\n3.) 4.9 cm3 refined halite\n4.) 236 cm3 partially hydrogenated tallow triglyceride\n5.) 177.45 cm3 crystalline C12H22O11\n6.) 177.45 cm3 unrefined C12H22O11\n7.) 4.9 cm3 methyl ether of protocatechuic aldehyde\n8.) Two calcium carbonate-encapsulated avian albumen-coated protein ovoids\n9.) 473.2 cm3 theobroma cacao\n10.) 236 cm3 de-encapsulated legume meats (sieve size #10)\nTo a 2-L jacketed round reactor vessel (reactor #1) with an overall heat transfer coefficient of about 100 Btu/F-ft2-hr, add ingredients one, two and three with constant agitation.\nIn a second 2-L reactor vessel with a radial flow impeller operating at 100 rpm, add ingredients four, five, six, and seven until the mixture is homogenous.\nTo reactor #2, add ingredient eight, followed by three equal volumes of the homogenous mixture in reactor #1.\nAdditionally, add ingredient nine and ten slowly, with constant agitation. Care must be taken at this point in the reaction to control any temperature rise that may be the result of an exothermic reaction.\nUsing a screw extrude attached to a #4 nodulizer, place the mixture piece-meal on a 316SS sheet (300 x 600 mm).\nHeat in a 460K oven for a period of time that is in agreement with Frank \u0026amp;Johnston's first order rate expression (see JACOS, 21, 55), or until golden brown.\nOnce the reaction is complete, place the sheet on a 25C heat- transfer table, allowing the product to come to equilibrium.\nFrom rec.humor.funny, as discovered on gopher://seanm.ca/00/stuff/eng-cookies.txt ","date":"January 14, 2007","externalUrl":null,"permalink":"/posts/2007-01-14-why-engineers-dont-write-cookbooks/","section":"Posts","summary":"Chocolate Chip Cookies Recipe\n1.) 532.35 cm3 gluten\n2.) 4.9 cm3 NaHCO3\n3.) 4.9 cm3 refined halite\n4.) 236 cm3 partially hydrogenated tallow triglyceride\n5.) 177.45 cm3 crystalline C12H22O11\n6.) 177.45 cm3 unrefined C12H22O11\n7.) 4.9 cm3 methyl ether of protocatechuic aldehyde\n8.) Two calcium carbonate-encapsulated avian albumen-coated protein ovoids\n9.) 473.2 cm3 theobroma cacao\n10.) 236 cm3 de-encapsulated legume meats (sieve size #10)\n","title":"Why Engineers Don't Write Cookbooks","type":"post"},{"content":"I found today something that (after long time) make me to say Wow! - and it had nothing to do with Apple or OS-X. Simple small system management utility for Windows modestly named System info, written by fellow Canadian Gabriel Topala (originally from Romania, but living in Toronto, as I found out from his resume on his web site).\nSo what is so fantastic about this program:\n- it is small (single file, 1.3 MB)\n- portable no installer required\n- free (although author welcomes donations and encourages registration)\n- amazing depth. It gives you more information than you expected, often more than you were aware you may get!\nThe main (and only) window of the program has three panes:\nThe navigation tree contains three main nodes: Software, Hardware and Network.\nUnder Hardware you will find:\nall disk information with free space, physical memory, all MB details (model, chipset, vendor, CPU type, socket, max speed, sensors information (CPU+disks temperature, voltage, fans), speed, bios maker, version, CPU information down to Feature Flags. You can e.g. verify if your CPU supports MMX instructions, virtual machine extensions or Processor serial number. Much more details than you wanted to know on system slots, devices, network card, video-card (including supported modes) and 3 screen long details on Direct X ...\nIn Network portion:\nyou can see e.g. ARP table, MAC addresses and IP addresses of computers around you, windows shares, open ports (inclusive program name which owns them and domain name of remote host it connects to), and wide variety of scans in network neighborhood: FTP, HTTP, NetBios, SQL Server, Telnet, VNC, Oracle, RDP ... you name it).\nSoftware\nBecause I am software developer, it were the features from Software subtree that made say Wow! few times. Let's start with details of the Windows XP (btw, including all service pack info and all installed patches, showing file name, version, installed data and for many of them with unistall command. As added value, it reveals the serial number and Windows XP product key which may come handy in case you lost the sticker.\nYou will get list of all installed applications with description, version and uninstall command. This list is MUCH more complete and detailed than what you get out of Control panel. For example, this are two entries for really old Java versions:\nName: Java 2 SDK Standard Edition v1.3.1_12\nVersions: empty\nUninstall: RunDll32 C:\\PROGRA~1\\COMMON~1\\INSTAL~1\\engine\\6\\INTEL3~1\\Ctor.dll,LaunchSetup \"C:\\Program Files\\InstallShield Installation Information\\{96539824-B716-11D7-88E8-0050DA21757E}\\Setup.exe\" -uninst\nName: Java 2 SDK, SE v1.4.2_03\nVersion: 1.4.2_03\nUninstall: MsiExec.exe /I{35A3A4F4-B792-11D6-A78A-00B0D0142030}\nThe list was 278 entries old on my 3 year old installation of XP.\nSpecial section \"Applications\" shows much more information for subset of installed programs. The much more in many cases (like Microsoft Office) means showing the product keys, serial numbers and versions of DLL's that belong to the package (e.g. Visual C++ Runtime)\nVery nice is File association section, which shows you name, path to executable and extension of the owner of every registered extension, as well all verbs (open, edit)\nAnd now the killer feature: Processes. SI displays PID, executable name, version, description, parent PID, number of threads, priority, process creation time, lifetime, kernel/user time, size and full path to executable. The Explore menuitem from context menu selects the executable in Finder, I mean Explorer. Clicking on process shows all loaded DLL's in lower panel (with path version, description, handle). The Loaded DLL's view goes the other way: upper panel shows all DLL's and after clicking on DLL you can see list of processes who loaded the DLL into their address space. Very interesting !\nExtremely informative is also the section Drivers and NT Services, audio/video codecs, registered ActiveX controls. What is also very useful is list of all open files, including the name and path of the process who opened them. This way you can e.g. see that Skype has open well over 30 file even if you are logged off and inactive - just by sitting in the system tray .. It is very eye opening exercise.\nSysadmins at heart will like the Groups and Users info: all details, inclusive SID, last logon, when and whether will password expire, group membership in one clean page.\nThe tool allows few interesting security hacks: \"Secrets\" lists all Form auto-complete passwords (for both IE and Firefox). It can also help you reveal the \"starred\" password typed into Windows form password fields using menu Tools-\u0026gt;Eureka. From Tools menu you can display all cookies, visited websites and Internet file cache.\nIf you are system administrator or have to keep few Windows machines alive and in good shape, you will want this tool. Go and give it a try - you will be very surprised what it can do for you. And if you find it useful, consider donation or registration - or at least try to help the author some other way (like spreading the word) - he deserves it !\n","date":"January 13, 2007","externalUrl":null,"permalink":"/posts/2007-01-13-the-amazing-free-system-information-utility-for-windows/","section":"Posts","summary":"I found today something that (after long time) make me to say Wow! - and it had nothing to do with Apple or OS-X. Simple small system management utility for Windows modestly named System info, written by fellow Canadian Gabriel Topala (originally from Romania, but living in Toronto, as I found out from his resume on his web site).\nSo what is so fantastic about this program:\n- it is small (single file, 1.3 MB)\n- portable no installer required\n- free (although author welcomes donations and encourages registration)\n- amazing depth. It gives you more information than you expected, often more than you were aware you may get!\nThe main (and only) window of the program has three panes:\n","title":"The amazing free System Information utility for Windows","type":"post"},{"content":"Lot's of things happening this week - Macworld and CES generated lots of activity in podcasts. Macbreak has interesting series of interviews done (mostly) by Leo Laporte and Merlin Mann with various people from Macworld. If you are interested how the author of Cocoalicious looks like in flesh, go and grab the few Macbreak episodes. There is also interesting interview with creators of the Modbook (Macbook based tablet), the Omni group, makers of the great OmniOutliner who recently release OmniPlan. It should be the first project management tool that does not suck. It is hard to believe that there can be a piece of software that contains Gantt diagram and is logical and usable \u0026lt;grin/\u0026gt; - it certainly does not apply to MS Project. I am really curious how the OmniFocus - the new GTD tool in preparation - will look like when it is done.\nSteve Gibson and Security Now! did not rest during holidays and his new series of podcasts is *very* interesting. It deals with DRM, content protection and Vista. He also did an interview with Peter Gutmann, the author of the white paper detailing the impact and cost of Windows Vista's content protection implementation to operating system users.\nWindows weekly brings episode duelling keynotes - Bill Gates vs. Steve Jobs. I can confirm they were quite different. One was like a perfectly prepared show, a focused work of art, briliantly delivered. The other was non-inspiring, kind of dull and partially off topic (what has the Office 2007 to do with electronic gadgets ?). Even if you consider differences in personalities and impact of jobsian reality distortion field, the comparison does not look good for Microsoft. Which is sad - I make my living on using almost exclusively Microsoft technologies for last 10 months, but I watched Steve Jobs keynote twice, and could not finished watching the other keynote even once.\nToo bad that the FLOSS (Free Libre Open Source Software) has no new episodes. There are soo many interesting people in OpenSource community that would make a great show !\n","date":"January 12, 2007","externalUrl":null,"permalink":"/posts/2007-01-12-from-latest-podcasts/","section":"Posts","summary":"Lot's of things happening this week - Macworld and CES generated lots of activity in podcasts. Macbreak has interesting series of interviews done (mostly) by Leo Laporte and Merlin Mann with various people from Macworld. If you are interested how the author of Cocoalicious looks like in flesh, go and grab the few Macbreak episodes. There is also interesting interview with creators of the Modbook (Macbook based tablet), the Omni group, makers of the great OmniOutliner who recently release OmniPlan. It should be the first project management tool that does not suck. It is hard to believe that there can be a piece of software that contains Gantt diagram and is logical and usable \u003cgrin/\u003e - it certainly does not apply to MS Project. I am really curious how the OmniFocus - the new GTD tool in preparation - will look like when it is done.\n","title":"From latest podcasts","type":"post"},{"content":"I had a discussion few days ago with a friend of mine on blogging. The topic was that as soon as something happens on the Net, thousands and sometimes even more people are writing, posting, discussing and blogging about the very same topic. A sort of information tidal wave that spreads across the cyberspace. Which was according to my friend huge waste of time and energy. Generally, he meant, from a whole community perspective, it makes no sense to write about something unless there is reasonable chance you will be saying something very unique that nobody else will likely say - otherwise it adds no value, just clutters the content by repeating and rephrasing the already said. At first it sounded reasonably sound ;-), but the longer I was thinking about it, the more I was convinced it may be quite the opposite.\nSo why is the repetition actually a good thing ? Because of Google. Think for a second about how the web search works: Google (or any other search engine) indexes the text of the retrieved Web pages and ranks them using the number of back-links (roughly said). It has no understanding of the content whatsoever, it does not classify or categorize Web pages - all it does is index the words and evaluates the links between pages. The people who are trying to search the Web, are using search phrases and get results from matching pages for the words from their search phrase, sorted by the ranking algortihm. What happens when many people are posting webpages or blogs about the same topic is that they will inevitably use different words and thus allow more search phrases return results. Because people who search will also use different variations of words, by adding new pages dealing with same topics you are actually increasing the chances that the searchers will find what they are looking for and making the search better. If the content creators also post links to similar pages, or their information sources, they are also helping the ranking algorithm to work better and are sort of \"promoting\" the pages they liked. This is very interesting voting mechanism from which we all benefit daily.\nTherefore, do not be shy to write your own opinion, valuation of event, technology, news or any ideas and do not worry about brazilions of other people doing the same. Even if very few people will actually read your stuff, the omniviscent Google will, and after scanning and indexing your page, your little bit will contribute to the shared pool of knowledge. And even if not, there will be always future you that will care what were you thinking about X.Y.Z. few years from now.\nWhenever you use some source, be nice and mention the reference - put the URL or backlink, and when quoting, make sure you say so. And remember that using copy and paste without proper attribution is cyber-plagiarism and it is worse for the well being of your cyber-identity than the supersized hamburger with boston cream donut is for your waistline: everything posted on the web stays cached for eternity and thanks to Google it is trivial to find out who used exactly the same words than you did :-)\nAnd do not worry, series of tubes that Internet is built from are not going to be clogged up just because you (and thousands people like you) will add one more page about iPhone :-)\n","date":"January 11, 2007","externalUrl":null,"permalink":"/posts/2007-01-11-repetition-is-the-mother-of-the-web/","section":"Posts","summary":"I had a discussion few days ago with a friend of mine on blogging. The topic was that as soon as something happens on the Net, thousands and sometimes even more people are writing, posting, discussing and blogging about the very same topic. A sort of information tidal wave that spreads across the cyberspace. Which was according to my friend huge waste of time and energy. Generally, he meant, from a whole community perspective, it makes no sense to write about something unless there is reasonable chance you will be saying something very unique that nobody else will likely say - otherwise it adds no value, just clutters the content by repeating and rephrasing the already said. At first it sounded reasonably sound ;-), but the longer I was thinking about it, the more I was convinced it may be quite the opposite.\n","title":"Repetition is the mother of ... the Web","type":"post"},{"content":"Just out of morbid curiosity I did the test, here is the result :-)\nYour Vocabulary Score: B-\nYou have a zealous love for the English language, and many find your vocabulary edifying.\nDon't fret that you didn't get every word right, your vocabulary can be easily ameliorated!\nHow's Your Vocabulary?\n","date":"January 10, 2007","externalUrl":null,"permalink":"/posts/2007-01-10-vocabulary-test/","section":"Posts","summary":"Just out of morbid curiosity I did the test, here is the result :-)\nYour Vocabulary Score: B-\nYou have a zealous love for the English language, and many find your vocabulary edifying.\nDon't fret that you didn't get every word right, your vocabulary can be easily ameliorated!\nHow's Your Vocabulary?\n","title":"Vocabulary test","type":"post"},{"content":"From today's Steve Jobs' keynote at Macworld 2007:\n\"I skate to where the puck is going to be, not to where it has been. \"\nWayne Gretzky\nI guess everybody is going to write about iPhone - which is OK because it is indeed very interesting gadget and it stole the show. To bad it will be 6 more months until it will be available in the US and (my best hopes) 8-9 months to have it here in Canada.\nThree other things what I secretly hoped that will be announced:\n1) a date when Leopard will be out (I kind of hoped it will be out when Vista hits the streets) and more details on features\n2) announcement that Mac Pro will be upgraded to dual-quadcore CPU. Would not it be great to have machine with 8 cores, 8 GB RAM and 2 TB diskspace ?\n3) ultra-light 10-11\" notebook with speech and writing recognition\nI guess we'll have to wait ...\nBut it was better than a movie. Great show, Mr. Jobs.\n","date":"January 9, 2007","externalUrl":null,"permalink":"/posts/2007-01-09-quote-of-the-day-3/","section":"Posts","summary":"From today's Steve Jobs' keynote at Macworld 2007:\n\"I skate to where the puck is going to be, not to where it has been. \"\nWayne Gretzky\nI guess everybody is going to write about iPhone - which is OK because it is indeed very interesting gadget and it stole the show. To bad it will be 6 more months until it will be available in the US and (my best hopes) 8-9 months to have it here in Canada.\n","title":"Quote of the day","type":"post"},{"content":"As I mentioned before, I am keeping all my bookmarks in del.icio.us account. Thanks to excellent Firefox extension and available bookmarklets, posting new URL's is very comfortable. After using the del.icio.us for some time, here is few tips how get best of it:\n- use the post buttons - they are available for Firefox as well as IE\n- post often and tag a lot. Tags are the only way how to search the non-public posts\n- keep consistent approach to tag names. I use singular, replace the '.' with word dot (dotnet) and write all lowercase\n- follow the crowd - consider using similar tags as others, it makes it easier to be part of community\n- use wisdom of the crowd. Look what else did other people tagged with the same tag as you did. You will be surprised what you may discover.\nYou can use the URL's creative way. To list all your bookmarks tagged with 'osx', enter http://del.icio.us/YOURUSERNAME/osx. To find out what anybody else tagged with 'osx', use http://del.icio.us/tag/osx. To see what is most popular with tag 'osx' use http://del.icio.us/popular/osx. You can see the pattern. It is also very easy to search URL's tagged with combination of tags, for example search all URL's tagged with all three tags\" 'osx', 'software' and 'free' use http://del.icio.us/tag/osx%2Bsoftware%2Bfree (the %2B is Web encoding of the '+' sign). You can also enter tags at the top of the home page:\nDel.icio.us offers very nice programmatic API, to retrieve/update/add list of posts, tags or bundles. This makes it very easy to integrate with other systems - and this is main reason why there are so many add-ons, tools and hacks available.\nHaving bookmarks on-line is what you want to do - they are not very useful without internet connection. As your collection grows, and you invest some time in organizing and cleaning up the collection, you may want to take some precaution that this effort will be not wasted if for some reason Yahoo decides discontinue the service: you want backup. Del.icio.us gives you option of doing backup, via Settings-\u0026gt;Export/Backup. If you want more, I found this wonderful page full of del.icio.us tools.\nI am right now evaluation the Mac-only offline Client WebnoteHappy which seems to be very promising and works exactly the way I like. It integrates bookmarks from Firefox, Safari and del.icio.us into one repository, allows you locally search, modify and manage the collection but post changes back to delicious. This way you can have best of both worlds: high user comfort and offline availability with local backup as well as on-line availability with synchronization. User interface resembles iTunes. There are still some minor with the program that I have not figured out - but this is what the evaluation period is for, right ?\nAlso very nice - and free - is also Cocoalicious offline client. It is fantastic help to consolidate and rename your tags. Rather then doing it through Web interface (see https://secure.del.icio.us/settings/USERNAME/tags/rename) you just rename the tag in Cocoalicious same way as you would rename file in Finder).\n","date":"January 8, 2007","externalUrl":null,"permalink":"/posts/2007-01-08-dealing-with-digital-mess-bookmarks/","section":"Posts","summary":"As I mentioned before, I am keeping all my bookmarks in del.icio.us account. Thanks to excellent Firefox extension and available bookmarklets, posting new URL's is very comfortable. After using the del.icio.us for some time, here is few tips how get best of it:\n- use the post buttons - they are available for Firefox as well as IE\n- post often and tag a lot. Tags are the only way how to search the non-public posts\n- keep consistent approach to tag names. I use singular, replace the '.' with word dot (dotnet) and write all lowercase\n- follow the crowd - consider using similar tags as others, it makes it easier to be part of community\n- use wisdom of the crowd. Look what else did other people tagged with the same tag as you did. You will be surprised what you may discover.\n","title":"Dealing with digital mess: Bookmarks","type":"post"},{"content":"I have to admit that I am suffering from severe case of installophobia. Every time I start installation program on Windows, I am very vividly imagining all the terrible things that may happen in next few minutes. Like overwriting some system DLL's with some old or wrong version which will break half dozen of other programs. Or messing up my registry so badly that I will have have to spend few days of backing up my system data and installing XP from scratch (and inevitably loose something very important in the process). The introduction of the system installer and MSI format few years ago helped a little for a while - up to the point when I wrote my first own installation program and fully understood what exactly can be done with it :-). Then it come back. I guess this may have contributed to two major shifts during last year - moving to Mac platform (which has no registry) and moving on-line (which has no install at all).\nUsing only Web based tools is an ultimate cure for installophobia and it gives you also ultimate portability. With Web based apps you do not need to carry anything with you - as long as you have internet connectivity, you are OK. As added benefit, all the tools are by definition multi platform and (almost always) OS agnostic. That almost part refers to small percentage of Web site who insist on using a feature available only in Internet Explorer - but their number seems to be decreasing.\nIf you are somewhere without connectivity you may still get the help against setupanxiety in the form of portable applications. They are just ordinary Windows application, which do not require installation and run from any place you have copied them - for example from USB key. I am wearing 1 GB USB stick on my keys for over a year now. I did not really use it too much - except occasional file transfer here and there, I had never have much use for it. Today I have decided to change it and create USB key toolset from (preferably) free and opensource programs.\nPortable applications I have copied on my key so far:\n- Package of Portable applications available from here. It contains Firefox (\"the\" browser), Thunderbird (\"the\" email client), Sunbird (calendar), GIMP (poor mans's Photoshop), ClamWin (antivirus), Miranda and Gaim (IM clients), OpenOffice, Abiword and VLC player plus few others. As added value, you will get a start program that that sits in system tray and makes access faster.\nI have also added few more apps:\n- Opera - alternative browser\n- NVU - the HTML editor\n- Notepad++ - programmers editor\n- Sysinternals tools\n- Total Commander - ultimate file manager, see the install hack\n- Hex editor - when text is not enough\n- KeePass - to keep secrets\n- FullSync - to keep things in sync\n- WinHTTrack - to download website\n- Neomem - a pretty neat notepad\n- Putty and WinSCP - no comments needed\n- xampp - full Apache webserver with PHP + PEAR, Perl, mod_php, mod_perl, mod_ssl, OpenSSL, phpMyAdmin, Webalizer, Mercury Mail Transport System for Win32 and NetWare Systems v3.32, JpGraph, FileZilla FTP Server, mcrypt, eAccelerator, SQLite, and WEB-DAV + mod_auth_mysql\n- TcpTrace, Http Fileserver,\nAs additional benefit of being careful with installers (on top of prolonging the lifespan of your Windows installation by delaying the registry cancer) you will also get easy cleanup (delete the directory and you are done), easy upgrade (delete old + xcopy new) and ability to carry your data with you (for example the bookmarks from portable Opera).\nIn fact, I am using the portable versions of the programs even on my desktop systems from the C: drive. This way I am not getting the same data portability as with USB key, true, but this is an excellent way how to run for example multiple versions of Firefox next to each other or use Opera without worrying which document types will the install program try to \"steal\" away.\nWhat are the drawbacks of portable apps ? Obviously, you will not get as good integration as with installed versions - e.g. with portable OpenOffice, the doubleclick on document will NOT start the text processor or spreadsheet - you have to start the program first and then open the file (or drop file on program window). Running from USB key is usually slower than from disk and key has smaller capacity. And USB key is easy to be lost, misplaced etc - so having a backup copy is always a good idea.\nOf course, the portable apps are no Windows specific thing - there are portable apps for OS-X as well. Nevertheless, Windows users will get most benefits of them, thanks to the fragility of the platform. And if you hoped (as I did) that Vista will be a big improvement in that registry nonsense, guess what ? Registry is still out there in Vista :-(. Therefore, guys - get ready to get out some productive mileage from our USB keys ... Or consider switching to Mac - no registry and install is drag'n'drop affair done in few seconds. Your choice.\nFew more portable apps that I still need to spend some time on:\n- portable Bash\n- free portable Python with IDE\n- fully portable Java (not terribly hard, but if you want to avoid conflicts with ancient versions in Windows directory, you need to change PATH and environment variables)\n- portable Eclipse (I know it can be done, just need to it do it properly. As soon as I am back to some Java project).\nIf you are into portable apps and have some time to kill evaluate software, this Wikipedia page is also worth looking at is.\n","date":"January 7, 2007","externalUrl":null,"permalink":"/posts/2007-01-07-installophobia-a-setupanxiety/","section":"Posts","summary":"I have to admit that I am suffering from severe case of installophobia. Every time I start installation program on Windows, I am very vividly imagining all the terrible things that may happen in next few minutes. Like overwriting some system DLL's with some old or wrong version which will break half dozen of other programs. Or messing up my registry so badly that I will have have to spend few days of backing up my system data and installing XP from scratch (and inevitably loose something very important in the process). The introduction of the system installer and MSI format few years ago helped a little for a while - up to the point when I wrote my first own installation program and fully understood what exactly can be done with it :-). Then it come back. I guess this may have contributed to two major shifts during last year - moving to Mac platform (which has no registry) and moving on-line (which has no install at all).\n","title":"Installophobia a Setupanxiety","type":"post"},{"content":"when it hangs and does not react. I am posting it so that I do not have to google it out again :-). Key is Menu + Select combination.\nHere comes the detailed version (saved from Google Notebook):\nToggle the Hold switch on and off to avoid \"hold trap\" Press and hold the Menu and Select buttons until the Apple logo appears, about 6 to 10 seconds. You may need to repeat this step. Tips:\n- set iPod set it on a flat surface.\n- Make sure the finger pressing the Select button is not touching any part of the click wheel.\n- make sure that you are pressing the Menu button toward the outside of the click wheel, and not near the center.\n- if battery is dead, above may not work, try to power the iPod - to a power adapter and plug the power adapter into an electrical outlet, or connect iPod to your computer. Make sure the computer is turned on and isn't set to go to sleep.\n- use only one finger from one hand to press the Center (Select) button, and one finger from the other hand to press the Menu button.\nAfter reset iPod music and files are saved, as well as date and time but some customized settings may be lost.\n","date":"January 6, 2007","externalUrl":null,"permalink":"/posts/2007-01-06-how-to-reset-an-ipod/","section":"Posts","summary":"when it hangs and does not react. I am posting it so that I do not have to google it out again :-). Key is Menu + Select combination.\nHere comes the detailed version (saved from Google Notebook):\nToggle the Hold switch on and off to avoid \"hold trap\" Press and hold the Menu and Select buttons until the Apple logo appears, about 6 to 10 seconds. You may need to repeat this step. Tips:\n","title":"How to reset an iPod","type":"post"},{"content":"It was Rod who started this by saying how great it is to replace slow typing with faster speaking and mentioning some kind of magical software package (appropriately named Dragon Naturally Speaking) which does transform your voice to written properly spelled English text with amazing accuracy. I was pretty sceptical, after seeing few years ago similar software from IBM with not-so-great accuracy, and even more recently the famous Vista speech wreckognition. Then Peter bought the software as well and had similarly good results as Rod. Now I got really interested. Both Peter and Rod and native speakers of English and I was very curious how will the software deal with my very own version of English pronunciation and fairly thick Slovak accent. So we did try it today.\nResult: amazing. This thing works. I had to read for about five minutes of predefined sentences in training mode and during this period the software created \"user profile\" capturing personal deviations and details about the way I speak. After that I tried to read half page from a book (it was technical book on UML design) and Dragon got whole text correctly except one word. No misspellings, no typos. That's much better result as if I would be trying to retype the paragraph by hand - and certainly much faster.\nAfter that, just for fun I tried to say something not in English. I said something like\n\"Und jetzt werde ich ausprobieren wie es reagiert wenn man auf Deutsch spricht\"\nI am not 100% sure about the exact wording - but it was some German variation on \"Now we will try out how it behaves whe I speak German\" and here was the amazing result:\nLet's missed it a software sock and deny Gary tomato salsa and yet in a vendetta dish.\nNo, I did not make this up - it is copied from email word by word.\nOf course, it is not a fair test, as the software was specifically set to US English. The company sells several language modules - including German, Italian and Dutch - which where not installed. I can imagine the result would be at least as good as with English - because English prononciation is probably most challenging for machine processing (why else would there be 3 separate modules - American English, Brittish English and Indian English). But it was fun anyway\n","date":"January 5, 2007","externalUrl":null,"permalink":"/posts/2007-01-05-speaking-to-the-dragon/","section":"Posts","summary":"It was Rod who started this by saying how great it is to replace slow typing with faster speaking and mentioning some kind of magical software package (appropriately named Dragon Naturally Speaking) which does transform your voice to written properly spelled English text with amazing accuracy. I was pretty sceptical, after seeing few years ago similar software from IBM with not-so-great accuracy, and even more recently the famous Vista speech wreckognition. Then Peter bought the software as well and had similarly good results as Rod. Now I got really interested. Both Peter and Rod and native speakers of English and I was very curious how will the software deal with my very own version of English pronunciation and fairly thick Slovak accent. So we did try it today.\n","title":"Speaking to the Dragon","type":"post"},{"content":"Today's extension is one that most people do not know about - and still almost everybody has it installed. The explanation for both is that it is distributed with Firefox, and unless you specifically prevent it's installation, you will get it. It is DOM Inspector.\nWhy would you care about something like this ? Unless you make living by creating Web applications, you probably would not. But if you do, it can help you a lot !\nTo open an inspector window for any page, select Tools-\u0026gt;DOM Inspector and press 'Inspect' next to URL (it copies URL of the page you are on, but you can type in any URL). The window is divided in three panes - document tree, node properties and in lower panel the rendered HTML. Now you can walk through the document tree and see the node properties (and note that in rendered page a blinking red rectangle will highlight the node you are on). Or you can go the other way - click on the top left button (\"Find a node ...\") and then click anywhere in the rendered document - the tree will reveal position of the element you are on. This is very usefull especially when you are trying to locate the chunk of HTML buried deeply in nested structures of tables.\nDOM Inspector will also help you see (and debug) the CSS and see the Javascript objects of the page. Best way how to find out, it to start experimenting. You can also get more information on how to use it, including nice snapshots on this and this blogs.\nIf you need less detailed information about the actual tree, but more summary type info on the page, try Ctrl-I (or Command-I on OS-X). It shows you page information dialog, with tabs for full HTTP headers (request as well as response), list of all links on the page, all media on the page (images, flash, ect) with option to save them to file, as well as information about everything that contributes to the rendered pages with its size.\nSo next time you will be trying to make sense of huge, complicated HTML source of a Web page, remember that help is only one click - Apple-Shift-I (or Ctrl-Shift-I for the Windows) - away.\n","date":"January 4, 2007","externalUrl":null,"permalink":"/posts/2007-01-04-feotd-well-hidden-secret/","section":"Posts","summary":"Today's extension is one that most people do not know about - and still almost everybody has it installed. The explanation for both is that it is distributed with Firefox, and unless you specifically prevent it's installation, you will get it. It is DOM Inspector.\nWhy would you care about something like this ? Unless you make living by creating Web applications, you probably would not. But if you do, it can help you a lot !\n","title":"FEOTD: well hidden secret","type":"post"},{"content":"I have got my eReader on 30th December, so after few days of playing with it, here are first impressions. I managed to read one book and played with it quite a bit, but I am still learning.\nThe quality of the display and \"electronic paper\" look and feel is great. It actually looks like paper, not like screen. The non-glossy texture surface has same visibility from every angle and it really reads like paper. I have no problem with the speed or lack of it - the page turn takes about 1-2 seconds, switching to full black and then redrawing is kind of cool when the page text \"emerges\" from the page. The picture is perfect, steady, does not strain the eyes, perfectly readable in sunlight. It is the best feature of the reader.\nDisclaimer: I have not tried the Sony eBook store, did not buy any DRM-protected eBooks and have no intention doing so. Actually I am going to avoid it like a plague. The prices of their eBooks are ridiculous (e.g. Michael Crichton Next costs $15.96 in ebook format compared to $25-$27 in paperback). If you think about economics, production costs and actual author's cut - this is pure greed. I only hope that the market will teach Sony a lesson and force them to get real - why would sane customer buy ebook which is locked to a new-to-market device with uncertain future ? Especially from company with such disastrous record when it comes to customer's right protection - anybody wanna rootkit ? Fortunately, there is enough content available without it.\nI have inserted SD card (thanks, Sony for not forcing us to go with otherwise useless Memory Stick) and loaded about 200 books in text, RTF and PDF format. The loading works only with supplied CONNECT software, so if you hoped (as I did) that you will copy the files on the notebook on the card and insert it, just forget about it. The CONNECT seems to be the only way how to get content on the device.\nThe same way as the screen of the reader is great, the CONNECT software is terrible. It tries to look like iTunes, but it fails in every aspect. It is sluggish on P4-3.2 GHz with 1 GB RAM (XP-Pro, do not blame Vista ;-)). It seems to \"freeze\" or lock up without visual indication while copying - and then it moves on. Uses 60-70-80% of CPU time. SO after about half an hour, I managed to have some content and started reading.\nThe absolutely best results are with TXT books, as long as you do not use hard line breaks, because - despite the many CPU cycles consumed - CONNECT did not bother reformat the paragraph and device obviously did not either. The device allows 3 or 4 sizes of the font. It does not allow to actually set the font, but the default font is OK.\nReading PDF files - which was one of the three main reasons I bought the device (next to large paper-like screen readable outdoors and long battery life) - was not so great. Imagine the lettersize page of PDF shrunk to the size of small paperback - less then half of the original. The characters are minuscule, very thin and pretty hard to read. Unlike with text, you have only two size options with PDF - bad and worse. Bad displays too small letters with no page margins, the worse adds some empty space around and makes the letters even smaller. Ouch. The only (partial) workaround is to switch the screen to landscape (by holding the size button for 5 seconds). In landscape the width of the page makes the characters almost well readable - for the price of seeing half of the page at once. I also noticed that one or two bottom lines in landscape appear to be \"grayed\" - probably software bug ?\nThe menu system looked strange at first, but then I got used to it. The device has limited bookmarking and navigation capability - you can store bookmarks, but you cannot search or jump to a given page. Partial compensation for it is history feature that remembers last pages per each book. If your books' file names are long and start with the author name, and you have several books from the same author, the book list display will be pretty useless - because all you will see is the first 15-20 character of the file name. There is also no option of annotating or marking anything in the text. I guess I can understand why. Combination of touch screen and e-ink is probably very hard problem to solve and features like search or annotate require user input.\nThe device offers option of viewing pictures and play MP3 (unprotected). The images look pretty good for the B\u0026amp;W screen - the grayscale is quite nice. I did not try the MP3 -IMHO the user interface is too impractical for real usage as player when you are used to iPod, and of course CONNECT is a bad joke compared to iTunes ...\nIf the above sounds like this is pretty terrible device, and I am sorry I spent about $450 CDN ($349 US plus Florida sales tax) - it is not true at all. I am very happy to have it, I actually like it a lot and use it as much as time permits. True, I had very high expectations, and except of the screen, Sony did not quite deliver. But it is version one - and not a bad version one. Let's hope there will be better firmware and most importantly better desktop software sometimes soon.\nHere is my wishlist of changes and improvements (in case somebody listens):\n- reformat TXT files during conversion to remove hard line breaks\n- \"reflow\" the PDF files to make shorter lines and readable font size\n- selectable font type and more font sizes\n- allow bold/italic for font selection\n- allow transfer files on SD card without CONNECT software - at least for TXT files\n- network capabilities - ideally wireless or at least Bluetooth - allowing either to access it as drive or (ideally) to use it as client to access network files\n- more intuitive navigation with \"breadcrumbs\" - showing where you are\n- show long filenames in two lines\n- thesaurus (for us non-native speakers of English)\n- paging buttons on both sides of the screen, not only on the left\n- text-to-voice (like Apple Macbook has)\n- clock, showing you the time in case you dive into book too deep :-)\nIn the meantime, if you are preparing the content for reading yourself, you can do several things to improve your reading experience: Format your text files and DOC files to avoid hard breaks and use only paragraphs. If you can generate PDF, try format and \"print\" it for custom page paper sizes - e.g. half-letter. This way the characters will be large enough to be actually readable.\nHappy reading.\n","date":"January 3, 2007","externalUrl":null,"permalink":"/posts/2007-01-03-sony-ereader-first-impression/","section":"Posts","summary":"I have got my eReader on 30th December, so after few days of playing with it, here are first impressions. I managed to read one book and played with it quite a bit, but I am still learning.\nThe quality of the display and \"electronic paper\" look and feel is great. It actually looks like paper, not like screen. The non-glossy texture surface has same visibility from every angle and it really reads like paper. I have no problem with the speed or lack of it - the page turn takes about 1-2 seconds, switching to full black and then redrawing is kind of cool when the page text \"emerges\" from the page. The picture is perfect, steady, does not strain the eyes, perfectly readable in sunlight. It is the best feature of the reader.\n","title":"Sony eReader - first impressions","type":"post"},{"content":"The 2006 was truly amazing year. We have accomplished so much - we have created the West end development centre, brought in and started several projects, completed phase 1 of employee conversion, started benefits program, ESOP program, redefined the company visual presence, grew the business and the company size considerably and created foundation for future growth.\nMost important achievemnt is the fun factor - I am again looking forward to go to work - and again since the Montage days the synergy is coming back. Thanks so much to all of you who helped it happen.\nIt was also very educational year. I have learned a lot about what running a business really means. Many things are so easy to understand, so common sense that you did not appreciate them, until the situation forces you to think hard and recognize the obvious.\nHere is seven common sense truth I have re-learned in 2006\n1) Hire by attitude, not by skills\nAttitude indeed does determine the altitude. Skills can be acquired, and helping people to grow in their skills is actually fun. The attitude is very hard to acquire and even harder to get rid off ... after certain age it is barely possible.\n2) Dare to risk\nNothing ventured, nothing gained. If we had waited with the new project until the contract is finalized, everything detail is clarified, all i's are dotted and all t's crossed, we would be still waiting. Now, we have made nice progress and are well on the road to completion.\n3) Work with client, not for client\nHaving mixed team - your own with customer's people can be both blessing and curse. We have decided to make it a blessing. And it became one.\n4) Prefer BFD to PFP\nThe BFD - bad first draft gives more value than Perfect Future Plan, for two simple reasons: the change invalidates much less the skeletal implementation than the plan and b), with BFD you have already made the first step, you see what is wrong and things are moving. Getting an imperfect solution and apply series of fixes is often the only practical way to completion - however wasteful it sounds - because with getting to BFD you have learned a lot about the business and environment what none PFP would ever reveal. This is especially true when you work against incomplete or ever changing requirements and scope\n5) Visual approach is the best\nUse cases have great value, but without user interface draft they may be (and will be) misunderstood. User interface mockup - even paper or whiteboard one - adds great value in removing the inclarities and validates the workflows in the use cases. See this book for more information\n6) Gradual changes win\nSeries of small improvements has better chance for success than an ambitious attempt to overdo the whole thing. If you are lucky, the small improvements you make will support and amplify each other -as the positive feedback. An example: since 2000, saved probably hundreds of hours of desperate searching by simple change: I dedicated EXACTLY ONE spot where I always hang my car keys after I return home :-). No rocket science - but how useful.\n7) Multitasking considered harmful\nThe better you manage to get everything else, except the one thing you are attending to, out of your head, the more success and fun you will enjoy. You can dress this simple truth to wide variety of psychological (The Present) and even spiritual packaging (mindful awareness of Zen, the Power of Now) but the basic message remains the same. Focus on the present moment. Wherever you are, be there. Trying to go to two different places simultaneously will get you to neither of them. So obvious ... and so true.\nLooking forward to new obvious truth I will discover this year :-).\n","date":"January 1, 2007","externalUrl":null,"permalink":"/posts/2007-01-01-looking-back-on-2006/","section":"Posts","summary":"The 2006 was truly amazing year. We have accomplished so much - we have created the West end development centre, brought in and started several projects, completed phase 1 of employee conversion, started benefits program, ESOP program, redefined the company visual presence, grew the business and the company size considerably and created foundation for future growth.\nMost important achievemnt is the fun factor - I am again looking forward to go to work - and again since the Montage days the synergy is coming back. Thanks so much to all of you who helped it happen.\n","title":"Looking back on 2006","type":"post"},{"content":"Today's topic is dealing with sensitive information - such as logins, passwords, PIN numbers, credit card numbers and so on.\nUp to last week, I was using the SplashID software to keep everything worth securing secure. I started to use SplashID back in 2001 when I bought the Palm based Sony Clie SJ30 (as replacement for wonderful Palm IIIxe). The Palm based program came with desktop counterpart that allowed editing of entries. Later in 2004 when I switched to Pocket PC, I simply purchased Windows Mobile version of the same software.\nSo - similarly as TheBat!, this was a legacy and similarly as TheBat! it had to go for two main reasons: closed source with proprietary format and Windows mostly. Technically, there is a Mac-OS-X desktop client for SplashID, but both Windows and Mac desktop clients are mainly add-ons to mobile platform counterpart. They focus on the problem of synchronizing one desktop with one or more) mobile device, but they do not do a good job in synchronizing two desktops.\nI also found out that I do not really use the Pocket PC for other purposes than reading eBooks and sometimes looking up phone number or address. Since I have MacBook, the later happens really rarely, because Macbook wakes up almost instantly and it takes about same time to find address on PPC and Mac.\nAfter some research and evaluation, I have decided to go with OpenSource solution KeePass. It is available for Windows as well as for MacOS and Linux, and in case I'd like to use my Toshiba again there is even a PocketPC version. The binary file format is 100% compatible - I tested out the file created on Windows works fine on Mac. I am not competent enough to judge the cryptographic capabilities of the system, but I trust the open source peer review process :-). The authors seem to know and care about security a lot - for example, after you copy password from entry edit form into clipboard, program automatically clears clipboard entry after defined amount of time (default is 10 seconds). Also user interface is very nice and what I liked is visual indication of the password strength - gives you some idea about how bad your passwords are. If you are really security conscious, it has nice generator of really strong passwords - the ones that you probably will not be able enter without clipboard.\nI still need to solve the issue of synchronizing different desktop. For now I do it with workflow: whenever I make a change in passwords or logins (this implies I am online), I sent myself an email with attached latest password file and enter ToDo to update other desktops. The file is very small - for few hundred entries ~ 50 kB. The file sits in my mailbox and is always available. When I receive new password file, I erase previous one in mail archive. Not ideal, but workable - because the frequency of adding new entries and changing passwords is not that high.\nA friend of mine is using USB stick on which he carries both the file as well as the KeePass software. This works too - assuming that you do not keep forgetting your USB key as I do. I have better results with email.\nFinal note to the conversion: it is possible to export the data as CSV file and import it to KeePass. What strangely was more efficient for me was to transfer the entries by opening both program and using clipboard entry-by-entry. This way I got rid of some really obsolete entries, verified many passwords and URL's and changed several long overdue password.\n","date":"December 31, 2006","externalUrl":null,"permalink":"/posts/2006-12-31-dealing-with-digital-mess-part-2/","section":"Posts","summary":"Today's topic is dealing with sensitive information - such as logins, passwords, PIN numbers, credit card numbers and so on.\nUp to last week, I was using the SplashID software to keep everything worth securing secure. I started to use SplashID back in 2001 when I bought the Palm based Sony Clie SJ30 (as replacement for wonderful Palm IIIxe). The Palm based program came with desktop counterpart that allowed editing of entries. Later in 2004 when I switched to Pocket PC, I simply purchased Windows Mobile version of the same software.\n","title":"Dealing with digital mess - Part 2: Passwords","type":"post"},{"content":"","date":"December 31, 2006","externalUrl":null,"permalink":"/tags/gtd/","section":"Tags","summary":"","title":"Gtd","type":"tags"},{"content":"I have decided to stop using Microsoft Outlook. No, I did not have any major issues with it, no horror stories of crashed, unreadable emails or viruses. As long as you use decent anti-virus (for example this one), switch off automatic loading of images and never do anything stupid such as clicking on an attachment or a link in email, you are reasonably safe. What got me to switch was lack of interoperability between anything non-Windows and Outlook and headaches of synchronization with on-line information. Using Outlook-only everywhere is not an option for me, because I need to use Mac as well as Windows and buying license of Outlook for every notebook, PC and virtual machine would be prohibitively expensive.\nDecision is easy step, what is harder is to implement it. Outlook is (was for me) 4 different things\n- email client\n- contact manager\n- to-do list manager\n- calendar\nI am lucky enough not be dependant on Exchange integration or on corporate shared calendaring solution, which is often one of the main reasons people are stuck with Outlook. Until recently, I also needed Outlook to keep my PocketPC synchronized with rest of the world. During few last month, I use my Toshiba e830 more and more are eReader device and less for actual information process, so this became less critical. Final blow came from unexpected angle - when I discovered the The Missing Sync. I can synchronize PocketPC on Mac, without needing the Outlook or even the Windows.\nTo completely avoid Outlook, I need to find reasonably good replacement for each of these 4 areas, so that the result is better, more open, location-agnostic and multi-platform. The result will probably less integrated than Outlook, but that's reality of Web 2.0 versus desktop applications.\n- For email, I have good solution in combination of GMail/Thunderbird (see yesterday entry).\n- For calendar, I am evaluating Google Calendar.\n- For ToDo's, my current favorite is Remember The Milk.\n- Right now, toughest part are contacts. Still working on this one.\nI will cover these in the coming days. Stay tuned.\n","date":"December 30, 2006","externalUrl":null,"permalink":"/posts/2006-12-30-how-to-get-rid-of-outlook-part-1/","section":"Posts","summary":"I have decided to stop using Microsoft Outlook. No, I did not have any major issues with it, no horror stories of crashed, unreadable emails or viruses. As long as you use decent anti-virus (for example this one), switch off automatic loading of images and never do anything stupid such as clicking on an attachment or a link in email, you are reasonably safe. What got me to switch was lack of interoperability between anything non-Windows and Outlook and headaches of synchronization with on-line information. Using Outlook-only everywhere is not an option for me, because I need to use Mac as well as Windows and buying license of Outlook for every notebook, PC and virtual machine would be prohibitively expensive.\n","title":"How to get rid of Outlook: the plan","type":"post"},{"content":"In certain sense, people and companies have one things in common. If have been around for few years, you collect, acquire or create very strange collection of tools, platforms, software and data formats. In short, you end up with lots of digital mess. I am planning to make major cleanup and streamlining in 2007 - consolidate the hardware, software, data formats and workflows both at home and at work.\nI have read the GTD book and many interesting articles and blogs on how people implement it. I noticed that the best way how to succeed is try to follow and customize the GTD approach for own circumstances, and build set of tools and processes that would make dealing with stuff easier, faster and more efficient.\nMost of my \"data stuff\" consists of:\n- email(s)\n- appointments and todo's\n- contacts and people information\n- passwords and sensitive information\n- links, bookmarks\n- chunks of information from the Web\n- active content (documents in process)\n- reference - finished documents , files\n- ebooks\n- music (MP3)\n- images and digital video\n- source code examples and chunks\n- backups, archives and data CD/DVD's\nI'd like to review and adjust all of the above over next month or so. I am saying next month - this is no new year resolution thing, it is more like convergence of the technology being available and size of the mess to deal with being uncomfortably large. Streamlining and simplifying email seems like good place to start - for one single reason: it keeps coming :-)\nDealing with Email\nHere is what I had up to last week on email side:\n- multiple email accounts (GMail, Yahoo, severals Rogers-Yahoo accounts)\n- multiple email clients on multiple platforms: Outlook and Thunderbird on Windows, Mail (and possibly Thunderbird) on Mac OS, none (only Web based access) on Linux\nThere are two basic workflows with email: one is daily use - reading/writing/answering. Occasionally you need to search back and find something for reference. The other is organizing, archival and searching for historical purposes. Unlike the first one, which must be done daily and from everywhere, the later can be executed from dedicated place, which allows the really old archives not be online. The setup I was using until this end of year was configuring each email client to leave messages on the server and then, using single \"sink\" once in a while I downloaded the old messages into archive. Sort of many-to-many setup, each client pulling emails from several on-line accounts. As result, I had many duplicate copies of emails on many machines. Every sorting and structuring of email was very time consuming and because there was never simple way how to \"repeat\" the cleanup/organizing from my desktop to my notebook, it was seldom done ... I was also never sure that any local client has complete snapshot - in case the client was down during archiving it could miss part of the conversations.\nI had two main goals on desktop side of email: to decrease the number of email clients to maximum 2 and define \"standard\" client. The format of the stored email must be open and client independent (to avoid lockup), must be multiplatform (so that I can move to Mac as main home platform as soon as Leopard is out) and must be programatically accessible (so that I can later process information from emails). The only email client that fits is Thunderbird, which fortunately uses open format, it is cross-platform, free and nicely extensible by plugins and there are many other good reasons for using it.\nThis also pretty much excludes Outlook as email client because it uses proprietary binary BLOB format with fairly bad track record of reliability and is (for all practical purposes) Windows only. For historical reasons, I was also using TheBat! for the \"sink\". Bat has same issues as Outlook, so the first task was to get my old emails out of the proprietary TBB format something more portable and more open.\nConverting TheBat! email to Thunderbird / mbox\nIt is very easy, but needs some manual work. In TheBat! you can export one folder at a time into Unix mbox format. You have to select all messages (Ctrl-A) in folder, select Tools -\u0026gt; Export, Unix mailbox and it is done. As long as you do not forget to select all messages, you will be fine. The resuting file is probably the most accessible and portable format you email can be in. You can easily import the emails from mbox to Thinderbird by free plugin mboximport. Conversion works like charm, including the attachements. The result is also very easily accessible - e.g. see examples using Python here.\nUnlike some people, I spend very little time working on my emails offline. For that reason, biggest simplification and improvement is using on-line email as base repository, rather than trying to keep it on desktops. This removes problems with email synchronization and makes it always available. The desktop clients are really meant to be used mainly for back-up and archiving, occasionaly for more comfortable editing or editing offline.\nWhen deciding between Yahoo and Google as main online platform, Google won. Both services give 2 GB free storage (Google right now almost 3 GB), both provide POP access. GMail user interface is however much more user friendly and lighter. Yahoo mail 2.0 is taking too much memory and power to run - and the old one is nowhere close to GMail. GMail also nicely integrates (by personalized Google home page) with Google Docs and Google Calendar which I am using a lot (and will need a lot for other categories of stuff).\nTo make Google central email hub is quite easy. You need to redirect other emails to GMail. Rogers-Yahoo allows that - after you set redirection email, you need to send verification request and enter code from received email - to confirm that you own the destination email address. After that, all works and all the spam that would otherwise be downloaded to your PC and filtered by excellent spam filters of Thunderbird, will be caught by GMail spam filters.\nAfter this, none of the Rogers email accounts in my machines are receiving any emails. In order to make all sent email from any PC or Mac available in global repository, it is necessary to add rule 'Bcc: my-gmail-account' in every Thunderbird email account that can be used for sending email. With this change, all is set.\nThe Thunderbird(s) and Mail.app are now used only for sending email and editing off-line emails (should it be necessary).\nGMail allows you to use multiple identities - you can set multiple From addresses and select (when writing new email) which one to use. This feature is available from Settings-\u0026gt;Accounts. Email addresses you use must be verified (by clicking on URL in verification email) to be addresses owned by you.\nThere is one \"feature\" of GMail that needs to be mentioned: when you have multiple clients who use POP to download GMail messages, unlike with my Rogers accounts, only first client downloads message. This can be used to your advantage when you set up one dedicated client to do frequent checks for new emails and all others to do no automatic checks - this way all your email will be automagically archived on one of your clients.\nWhat are achievements of all these changes:\n- all my email is available on-line via GMail (platform agnostic)\n- all clients are more or less just convenience how to send email when working offline\n- all email is archived in one place (home desktop), in open and portable format (Thurderbird mbox). Most of email still stays on-line\n- there are no duplicates of emails in the clients\n- rather than trying to sort emails into folders, I use tags and Archive feature of GMail. Searching works good enough and whole process is much faster.\n- Outlook as email client is gone, as well as problems with PST format (like synchronization)\n- TheBat! as email client (archiving sink) is gone, archiving is now platform-agnostic mbox. Old archives are converted to mbox.\nNice start !\n","date":"December 29, 2006","externalUrl":null,"permalink":"/posts/2006-12-29-dealing-with-digital-mess-part-1/","section":"Posts","summary":"In certain sense, people and companies have one things in common. If have been around for few years, you collect, acquire or create very strange collection of tools, platforms, software and data formats. In short, you end up with lots of digital mess. I am planning to make major cleanup and streamlining in 2007 - consolidate the hardware, software, data formats and workflows both at home and at work.\nI have read the GTD book and many interesting articles and blogs on how people implement it. I noticed that the best way how to succeed is try to follow and customize the GTD approach for own circumstances, and build set of tools and processes that would make dealing with stuff easier, faster and more efficient.\n","title":"Dealing with digital mess - Part 1","type":"post"},{"content":"During over 8 years living on this continent I've developed reasonably thick skin in dealing with business calls, unsolicited mailings and other annoyances of aggressive selling. I was pretty sure nothing can make me really upset. Up until yesterday. Thanks to amazing capability of the Direct Energy sales force who does not take No for an answer.\nBut let's start from the beginning. About 3 weeks ago I started to get frequent calls from Direct Energy about their flat rate plan. After avoiding them few times, I realized that they will not give up and answered the call. I have got myself into a discussion with guy who wanted me to lock up my price per kWh for next 5 years. Sort of protection plan. The idea is that you pay same amount - starting with higher than market price - and as the price goes up, you may end up to be better off over time.\nAs I never buy anything from a telemarketer, I said no. Upon insistence, I agreed that it is OK to mail me information about the prices and so on. I was very explicit to repeat about three times that I am not ordering anything, or enrolling into any plan - and the guy agreed. Just an information - no obligations.\nNow guess what: yesterday I have received a letter starting with sentence \"Thanks for enrolling into flat rate ...\". That got me really going. I had to call customer support just to find out that I was indeed enrolled. I cancelled, of course, but feel this is such rude and inappropriate behaviour, that it deserves some publicity.\nWhat is proper English term for this \"business\" method - when a sales person is openly lying to you ? It is not false advertisement. In that case, the consumer decides to buy based on incorrect information - but at the end, it is the customer that says yes and decides to buy. I am not a lawyer, but what happened sounds like fraud to me - I was put in position to be paying for something I have not ordered. And because one can safely assume I was not the only case they have tried it on, maybe even a scam ? It would not be the first time:\nhttp://www.ontariotenants.ca/electricity/articles/2003/cp203f20.phtml\n\"Direct Energy Marketing Ltd. and Ontario Energy Savings Corp. have been fined a total of $232,500 after some of their agents apparently forged signatures on 31 consumer contracts, the Ontario Energy Board said today. Direct Energy was fined $7,500 for each of the 21 switched consumers and Ontario Energy Savings Corp. was fined the same amount for 10 switched consumers.\"\nThe only difference is that now, they are not even bothering to fake your signature - they just sign you up, because you have answered the phone.\nThere seems to be nothing wrong with the idea of locking down the rate you pay for electricity for 5 years. Assumed that a) the prices will go up by predictable amount and b) you will indeed be able to get electricity or whatever you paid for for the full duration of the contract. There is even sound business plan behind - with enough subscribers, you can buy in large quantities with discount and have decent margin. What happened to a friend of mine was that he enrolled and paid about 2 years higher price. On year 3, the company he had contract with claimed bankrupcy and the new company promptly offered new 5 year plan - for a price about 30% above market price in year three. Hmm, how very convenient ...\nAs Hanlon's razor says Never assume malice when stupidity will suffice. Last week, I would give them benefit of the doubt. Not today, I am afraid.\nLesson learned - never ever go to any discussion with a business caller. If you want to save time and do not mind sound rude, just say NO and hang the phone on them. If you want to invest some time and avoid being rude, here is what you can do: start recording the phone calls and tell the bugger you are doing so. Ask them to remove your name and phone number from their list - technically, they should be oblidged to do so when you ask. You can also ask for the intruder's name, home address and home phone number - why should only you have to provide private information to him/her ? Ask also for the name of the manager or superior, his or her home phone number. When they ask why, tell them that you would like to call them at home, in their private space just to let them experience how it tastes when an unwelcomed stranger interrupts whatever they are doing and steals their time talking about some stupid braindead useless product or service. Let them feel the pain.\n","date":"December 28, 2006","externalUrl":null,"permalink":"/posts/2006-12-28-sales-as-con-art-or-welcome-to-direct-energy-flat-rate-plan/","section":"Posts","summary":"During over 8 years living on this continent I've developed reasonably thick skin in dealing with business calls, unsolicited mailings and other annoyances of aggressive selling. I was pretty sure nothing can make me really upset. Up until yesterday. Thanks to amazing capability of the Direct Energy sales force who does not take No for an answer.\nBut let's start from the beginning. About 3 weeks ago I started to get frequent calls from Direct Energy about their flat rate plan. After avoiding them few times, I realized that they will not give up and answered the call. I have got myself into a discussion with guy who wanted me to lock up my price per kWh for next 5 years. Sort of protection plan. The idea is that you pay same amount - starting with higher than market price - and as the price goes up, you may end up to be better off over time.\n","title":"Sales as Con Art - or welcome to Direct Energy flat rate plan","type":"post"},{"content":"One of the most successful presents this Christmas was five copies of the same book. Not just some kind of a book. Our daughter got five copies of the book she authored as a surprise. How can this happen ?\nI was toying with an idea to try out self-publishing on-demand printing company that would allow you to create and publish book without spending hundreds or thousands of dollars as investment - sort of \"pay as go\" plan. The only way how to do it is create the the printable book yourself and find publisher that can do print on demand. Most companies that I found were selling packages in price segment $800 to few thousands of dollars, which included professional assistance in book creation: proofreading, editing, graphics design etc. One company however, offered exactly what I needed: a service that allows you to upload content file, design the cover and order as little as single copy - or as many as you need. No setup fees, publishing packages or minimum orders. See www.lulu.com for more detail. So we have decided to give it a try. It was an easy decision because manually printing the color pages and paying for binding would cost about 3 times more as was the price on Lulu.\nYou do not need any special software to create content - Microsoft Word document, RTF or PDF will do fine. If you upload DOC, Lulu converts it PDF for you and gives you a preview of the final product. Because the files can be big - sometimes too big for HTTP upload, Lulu offers FTP upload service.\nI had no commercial intentions with the book, I just wanted to create a great gift. You can, however, decide that you want to publish for profit: Lulu gives you per-copy production cost, you set the price and from the difference, Lulu gets commission. You keep the copyright, you can decide whether the book is private (available only to you) or public - available to everybody. You can also for about hundred bucks purchase a distribution service - your book will get real ISBN and will be available for order from Amazon or Barnes\u0026amp;Noble and independent stores.\nThe on-demand printing takes about 10 business days for paperbacks, 15 days for hardcovers. We have received our books on time, despite the pre-Christmas volume. I have also exchanged few emails with technical support: their answers were fast professional and actually helpful - a quality not seen so often seen these days (hi there, Internet cable company, speaking of you).\nThe quality of the books is excellent. Very good printing, great color reproduction and good paper. It made perfect present, made our daughter very proud and me and my wife very happy. Highly recommended. In case you want to see the book, here it is. It is even available for ordering :-). Big thanks to Lulu for making it possible.\nDisclaimer: I am in no form affiliated with the Lulu.com. I just liked the idea and enjoyed their great service. ","date":"December 27, 2006","externalUrl":null,"permalink":"/posts/2006-12-27-publish-your-own-book-or-lulucom-rocks/","section":"Posts","summary":"One of the most successful presents this Christmas was five copies of the same book. Not just some kind of a book. Our daughter got five copies of the book she authored as a surprise. How can this happen ?\nI was toying with an idea to try out self-publishing on-demand printing company that would allow you to create and publish book without spending hundreds or thousands of dollars as investment - sort of \"pay as go\" plan. The only way how to do it is create the the printable book yourself and find publisher that can do print on demand. Most companies that I found were selling packages in price segment $800 to few thousands of dollars, which included professional assistance in book creation: proofreading, editing, graphics design etc. One company however, offered exactly what I needed: a service that allows you to upload content file, design the cover and order as little as single copy - or as many as you need. No setup fees, publishing packages or minimum orders. See www.lulu.com for more detail. So we have decided to give it a try. It was an easy decision because manually printing the color pages and paying for binding would cost about 3 times more as was the price on Lulu.\n","title":"Publish your own book - or Lulu.com rocks!","type":"post"},{"content":"I had a brief MSN chat with friend of mine today, who tried to install and use Vista as development platform. I mean install on the real hardware, in order to use it as core operating system. I have no feedback yet on how Visual Studio works, but as he found out, his Ant build files he uses to compile and deploy Java programs stopped working - because Vista did not allow to copy Javascript files. I can understand why Javascript files are treated with caution - however, it should not be considered the same when a file is copied from a local file to a local file, rather then downloaded from the internet.\nProblems like this one were not occuring on XP for two main reasons: one becase XP security was nowhere at the same level and two because pretty much every developer was running XP as administrator. Using an admin account for everyday work is bad for security and Microsoft tried hard to create system that would be actually usable when logged on as standard non-priviledged user.\nIf suprises like this one occur too often, people will likely decide to go back running as administrators again ... which beats the idea of having better security under Vista. If I think about it, all code related demos at the \"Ready for the new day\" were done under administrator account. Is it because this is the only practical way how to develop application under Vista ?\nI guess Steve Gibson's scepticism about early adoption of Vista was not far off (again). Let's wait for real stories from real use scenarios and maybe even a Service Pack 1 - and then evaluate whether Vista is already prime-time ready for a developer.\n","date":"December 26, 2006","externalUrl":null,"permalink":"/posts/2006-12-26-vista-security-and-java/","section":"Posts","summary":"I had a brief MSN chat with friend of mine today, who tried to install and use Vista as development platform. I mean install on the real hardware, in order to use it as core operating system. I have no feedback yet on how Visual Studio works, but as he found out, his Ant build files he uses to compile and deploy Java programs stopped working - because Vista did not allow to copy Javascript files. I can understand why Javascript files are treated with caution - however, it should not be considered the same when a file is copied from a local file to a local file, rather then downloaded from the internet.\n","title":"Vista security and Java","type":"post"},{"content":"Despite Sony's attempt to ignore non-US markets and leave Canadians in the cold (pun intended, even if it is still above zero), I have become a proud owner of the wonderful gadget for all eBooks fans. I still do not have it physically, so I cannot put it under the tree. It is coming next week, when my friend who now enjoys the vacation down in the south returns. He was not only very kind to buy one for me too, but he also wrote a wonderfull review which he is going to post on the Net. I will add a link as soon at it happens. Until that time, here is the summary, in his very own words:\n\"So in short, I am really impressed by the Sony eReader. Everything from case construction, functionality, file format support, screen resolution, and most importantly the actual readability of the unit all hit the target. You really have to see it to believe it. The only negative comments are the lag-times between screen refreshes, and the somewhat unintuitive menu navigation. As far as future functionality (wish list), I can imagine that full color support will be the next thing on the list, as well as searching and annotation of documents, and maybe even support for wireless connectivity for good measure. \"\n","date":"December 24, 2006","externalUrl":null,"permalink":"/posts/2006-12-24-got-the-sony-reader/","section":"Posts","summary":"Despite Sony's attempt to ignore non-US markets and leave Canadians in the cold (pun intended, even if it is still above zero), I have become a proud owner of the wonderful gadget for all eBooks fans. I still do not have it physically, so I cannot put it under the tree. It is coming next week, when my friend who now enjoys the vacation down in the south returns. He was not only very kind to buy one for me too, but he also wrote a wonderfull review which he is going to post on the Net. I will add a link as soon at it happens. Until that time, here is the summary, in his very own words:\n","title":"Got the Sony reader :-)","type":"post"},{"content":"I have discovered recently the nice feature of Wordpress - Dashboard which shows number of visits, but also shows incoming links and search phrases the people used to land on my blog. Sometimes, they provide really interesting and surprising insights. Of course, I do not see who they are or where the visitors are coming from - so no privacy concerns.\nBecause of my first name (which is btw abreviated form of Miroslav), I am getting some visits from the people interested in the works of Joan Miró - spanish/catalan artist. Must be quite a disappointment for them, sorry. Nothing to do with visual arts here - unless you count art of coding ;-).\nHere are few examples:\n- books about miró - see above.\n- Linkify Firefox extension\n- mac open .cdr image\n- fedex memphis ottawa apple - looks like somebody else from Ottawa is expecting Mac delivery\n- weird spreadsheets - how did I got to this one ?\n- ready for a new day event - maybe marketing department is checking feedback\n- C# 3.0 versus Java - I plan to get back to C# vs Java\n- firefox linkify - surprisingly, Linkify extension get's a lot of searches.\n- undocumented Miro - what the heck is this ?\n- c# ORM Dynamic Method - good idea for an entry\n- c# mixing compiled and dynamic code - I'd look at IronPython first, folks,\n- business objects c# 3.0 - after my project is over, I'll do a summary of \"Doing business objects with CSLA - lessons learned\"\n- miro's world - I like this one, somebody who knows what to search for :-)\n","date":"December 23, 2006","externalUrl":null,"permalink":"/posts/2006-12-23-statistics-are-fun/","section":"Posts","summary":"I have discovered recently the nice feature of Wordpress - Dashboard which shows number of visits, but also shows incoming links and search phrases the people used to land on my blog. Sometimes, they provide really interesting and surprising insights. Of course, I do not see who they are or where the visitors are coming from - so no privacy concerns.\nBecause of my first name (which is btw abreviated form of Miroslav), I am getting some visits from the people interested in the works of Joan Miró - spanish/catalan artist. Must be quite a disappointment for them, sorry. Nothing to do with visual arts here - unless you count art of coding ;-).\n","title":"Statistics are fun","type":"post"},{"content":"Unfortunately, as of previous Sunday I have run out of the backlog in Security Now! episodes, which means that with all three of my favorite podcasts (Twit, Windows Weekly and Security Now!), I am pretty much dependent on their weekly releases. This is a problem, because the sum of 5-7 weekly commutes to work and back (about 15 minutes one way) plus about 40 minutes in a gym every day equals to about 6 hours of required podcast quality content, and the new episodes of three podcasts above cover barely half of it.\nSo I needed to enhance the podcast menu. Here is what seems to work and what worked less:\n1) Merlin Man's 43folder podcast. As with Steve Gibson, I listened up to the current one and enjoyed it a lot, specially the episodes with David Allen. Fast paced, entertaining, informative. I liked Merlin humor.\n2) FLOSS - do not run away, this has nothing to do with that scary profession, it stands for Free Libre Open Source Software. I started to listen from the beginning. It is interesting to hear the people you know through their code or technical achievements as living human beings. The quality of the podcast (both audio and moderation) is not as good as other Twit series - but I guess Leo cannot be everywhere and content is heavily dependent on the guest. So far I am at episode 4, the episode #2 with Ben Goodger (Firefox) was interesting, the #3 (Rob Malda aka CmdrTaco of Slashdot) was not so great.\n3) Cranky Geeks. Run and moderated by John C Dvorak. First I thought this will be something as good as TWIT, but it was not quite so. Maybe it's selection of the guests, maybe selection of the news they focus on, but IMHO John put together with few more cranky geeks without compensation of basically positive, enthusiastic person such as Leo leads to overcrankyfication (at least for my taste buds). Second - the commercial breaks. There are way too many and way too annoying. I can accept TWIT's 2-3 commercial plugs about Dell, Vista or Astaro, but this is an overkill. If John does not make you cranky, the ads will. Use with moderation :-)\nI have also downloaded back episodes 1 to 45 of Security Now! which were not in iTunes subscription - at least I have not discovered how to make them apper there from the grc.com and will listen to them. Unlike the news based podcasts, the topics are still very valid and relevant. Thanks, Steve and Leo - you are fantastic.\n","date":"December 21, 2006","externalUrl":null,"permalink":"/posts/2006-12-21-few-more-podcasts/","section":"Posts","summary":"Unfortunately, as of previous Sunday I have run out of the backlog in Security Now! episodes, which means that with all three of my favorite podcasts (Twit, Windows Weekly and Security Now!), I am pretty much dependent on their weekly releases. This is a problem, because the sum of 5-7 weekly commutes to work and back (about 15 minutes one way) plus about 40 minutes in a gym every day equals to about 6 hours of required podcast quality content, and the new episodes of three podcasts above cover barely half of it.\n","title":"Few more podcasts","type":"post"},{"content":"","date":"December 20, 2006","externalUrl":null,"permalink":"/tags/ui/","section":"Tags","summary":"","title":"Ui","type":"tags"},{"content":"Quite seldom I see something on the net that is elegant, beautiful, and simple - so simple that it becomes obvious. Last time I had this feeling was with iPod's wheel.\nThere was lots of excitement about new Vista user interface features. The users who never used / saw OS-X, must love Vista. It is huge improvement over XP - much nicer, cleaner, very good typography, comes very close to Tiger. Linux users have their own great looking desktop XGL. From human-machine interaction point of view, neither Vista, nor XGL did really bring anything new - just caught up with Apple and added few eye candies on top. All this 3D-turning, spongy shaking windows, transparencies and rotating planes look indeed nice, but add very little to the functionality of Expose (besides, no one except Apple has two finger trackpad scrolls). So what is so cool about the BumpTop ? Everything.\nUser interface paradigm demonstrated in BumpTop prototype combines 3D graphics and physics in very new and creative ways. But see for yourself. The site offers hi-res videos in QT and WMV formats as downloads or torrents. The Youtube link to low res version is here. The lasso-n-cross idea and pile/unpile are so impressive. Enjoy !\n","date":"December 20, 2006","externalUrl":null,"permalink":"/posts/2006-12-20-unlike-vista-this-user-interface-is-something-new/","section":"Posts","summary":"Quite seldom I see something on the net that is elegant, beautiful, and simple - so simple that it becomes obvious. Last time I had this feeling was with iPod's wheel.\nThere was lots of excitement about new Vista user interface features. The users who never used / saw OS-X, must love Vista. It is huge improvement over XP - much nicer, cleaner, very good typography, comes very close to Tiger. Linux users have their own great looking desktop XGL. From human-machine interaction point of view, neither Vista, nor XGL did really bring anything new - just caught up with Apple and added few eye candies on top. All this 3D-turning, spongy shaking windows, transparencies and rotating planes look indeed nice, but add very little to the functionality of Expose (besides, no one except Apple has two finger trackpad scrolls). So what is so cool about the BumpTop ? Everything.\n","title":"Unlike Vista, this user interface *is* something new","type":"post"},{"content":"Few good links I've received from friends:\n- Interesting satelite images of Earth;\n- New way how to discover / browse music - http://www.musicovery.com/\n- All Web 2.0 sites directory, implemented Web 2.0 way\n- On-line media conversion tool. Great for converting MP3 to ringtones :-)\n- If you fly often, the SeatGuru will help you choose good seats and avoid bad ones\n- interesting slow motion videos - http://www.redlake.com/gallery/videos/RDT.aspx\n- animated knots\n- nicely done Web2 (laszlo based) tool for selection of matching colors\nand a nice quote:\nThere is no failure. Only feedback.\n","date":"December 19, 2006","externalUrl":null,"permalink":"/posts/2006-12-19-surfmania/","section":"Posts","summary":"Few good links I've received from friends:\n- Interesting satelite images of Earth;\n- New way how to discover / browse music - http://www.musicovery.com/\n- All Web 2.0 sites directory, implemented Web 2.0 way\n- On-line media conversion tool. Great for converting MP3 to ringtones :-)\n- If you fly often, the SeatGuru will help you choose good seats and avoid bad ones\n- interesting slow motion videos - http://www.redlake.com/gallery/videos/RDT.aspx\n- animated knots\n- nicely done Web2 (laszlo based) tool for selection of matching colors\n","title":"Surfmania","type":"post"},{"content":"Using PocketPC with Windows is very easy, assumed that you are using Outlook. Synchronization is straightforward, works out of the box. If you are keeping your contacts in other software than Outlook, you can often find 3rd party software that does the synchronization - or at least provides the plugin. The selection of the solutions is fairly large.\nOn Mac, you are in similar situation if you want to use Palm based PDA. With Pocket PC synchronization, selection is limited. For direct synchronization between Mac address book and iCal, you have basically 2 options (or more precisely, at least two options): PocketMac or The Missing Sync. Both will do the job, but the Missing Sync seems to be more modern: it supports Intel processors on Mac side and Windows Mobile 5. Also the Web site of the Missing sync has more professional, Mac-like look. I found the review of both, but little bit dated ...\nIf you need synchronize contacts between Mac, Windows and Pocket-PC, it is more complicated. What worked for me was using on-line Contact repository http://www.plaxo.com/. As long as you are willing have your contacts on-line, you can use this free service. Great feature of Plaxo is that is has plugins for both Outlook and Thunderbird as well as Mac Address Book. This way you can keep contacts in your email clients synchronized and have a Web access to your contacts on-line. I was using this setup before I started to use Mac to keep multiple address-books on multiple machines in sync - one Outlook, two Thunderbirds - as well as synchronize with Pocket PC. Actually, using Pocket PC was main reason to keep using Outlook. Now with Missing Sync, I can re-evaluate the need and maybe get rid of it.\n","date":"December 18, 2006","externalUrl":null,"permalink":"/posts/2006-12-18-how-to-synchronize-pocket-pc-with-mac/","section":"Posts","summary":"Using PocketPC with Windows is very easy, assumed that you are using Outlook. Synchronization is straightforward, works out of the box. If you are keeping your contacts in other software than Outlook, you can often find 3rd party software that does the synchronization - or at least provides the plugin. The selection of the solutions is fairly large.\nOn Mac, you are in similar situation if you want to use Palm based PDA. With Pocket PC synchronization, selection is limited. For direct synchronization between Mac address book and iCal, you have basically 2 options (or more precisely, at least two options): PocketMac or The Missing Sync. Both will do the job, but the Missing Sync seems to be more modern: it supports Intel processors on Mac side and Windows Mobile 5. Also the Web site of the Missing sync has more professional, Mac-like look. I found the review of both, but little bit dated ...\n","title":"How to synchronize Pocket PC with Mac","type":"post"},{"content":"","date":"December 18, 2006","externalUrl":null,"permalink":"/tags/pocketpc/","section":"Tags","summary":"","title":"Pocketpc","type":"tags"},{"content":"On my way home from the office (yes, I know, technically it was Sunday) I stopped at my favorite Chapters store just to check what is new. First stop is always magazines, partially because it is right next to the entrance, partially because it is on the shortest path to Starbucks counter inside Chapters. For many years, there used to be two shelves with computer magazines. Now there is only one. And half of the magazines are about Photoshop, iPods and digital gadgets. Not that there was anything wrong with Photoshop and iPods - I love my iPod and have deep respects for Photoshop capabilities (albeit I can hardly use the Elements). What I miss are good old fashioned developers mazines which have dimisnished almost completely.\nBack in 1998-2000 there used to be dozens of developer oriented magazines: Java Report, Java Developers Journal, JavaPro, Dr. Dobbs, Software Development, Microsoft Systems Journal (later MSDN Magazine), C++ Report, PHP magazine, ASP.NET Pro and many others. Plus many operating systems specific magazines: several Linux oriented, few Windows and lots of Mac specific. Today pretty much all of them are gone. Some because they have stopped to be printed on paper or published completely, most of them probably because Chapters stopped ordering them. Occasionally I see ASP.NET Pro, but most of the shelf represents very consumer oriented view of the computing world.\nIt is probably inevitable trend: more and more advertisement goes online, away from printed media, and the content must follow. Old style media are being replaced by digital. Same as with film cameras and VHS. But is sort of sad to realize that you will have to consume articles about \"Greatest MP3 players of the year\" with your chai latte, rather than enjoying juicy and intellectually stimulating Dr. Ecco's Omniheuristic Corner from printed copy of the Dr. Dobbs. Right now, you can still read it online - assumed that you have your notebook with you and are willing to pay for overpriced WiFi connectivity on top of overpriced coffee. Unfortunately, the WiFi connection in Canadian Starbucks is not free, you will be likely better off to go to Bridgehead, they have better coffee with organic cream and milk ... but no Chapters attached ...\nAnd btw, today is day 30 of the 30 day challenge :-). I did it !\n","date":"December 17, 2006","externalUrl":null,"permalink":"/posts/2006-12-17-disappearing-act-of-computer-magazines/","section":"Posts","summary":"On my way home from the office (yes, I know, technically it was Sunday) I stopped at my favorite Chapters store just to check what is new. First stop is always magazines, partially because it is right next to the entrance, partially because it is on the shortest path to Starbucks counter inside Chapters. For many years, there used to be two shelves with computer magazines. Now there is only one. And half of the magazines are about Photoshop, iPods and digital gadgets. Not that there was anything wrong with Photoshop and iPods - I love my iPod and have deep respects for Photoshop capabilities (albeit I can hardly use the Elements). What I miss are good old fashioned developers mazines which have dimisnished almost completely.\n","title":"Disappearing act of computer magazines","type":"post"},{"content":"Weekend time again. As few times before, here are few discoveries from the Web:\nGoogle is pushing Internet Explorer 7. Their own version, using new Internet Explorer Administration Kit. It is not really different version - just configured with Google as default search engine and Google toolbar. Nothing that little more experienced user would not do himself. I am not sure how successfull this will be - but I am pretty sure that this was not what Microsoft had in mind how this tools should be used for.\nNY Times offers pretty entertaining series of videos with David Pogue. Over forty pieces, several of them are relly funny.\nGuess which country has most IP adresses per capita ? No, neither USA, nor Japan, nor the Scandinavian countries, it is Vatican. USA is second, Canada third (thumbs up !!). More countries are here. No surprises on the other side of the scale: Ethiopia, Niger, Congo.\nInteresting article how Google keeps employees: by treating them like kids. Very interesting. Should I have had an option at the time of finishing my university studies, to extend my student life by few more years - I would have likely gone for it. I even tried it by accepting a job at the University, but it was not the same. Obvious why - different time and no Google ...\nFew blogs that caught my attention:\nMirkwood - blog about reading. See also the recommended links on similar blogs ...\nSharing the truth one thread at the time. - despite the religiously sounding title, this one is about technology. Interesting reads.\nThis one is classic: Merlin Mann's 43folders Check it out if you do not know it. I mention it because I listened to few Merlin's podcasts and liked them. Worth looking at is also Wiki and forum.\n","date":"December 16, 2006","externalUrl":null,"permalink":"/posts/2006-12-16-weekend-special/","section":"Posts","summary":"Weekend time again. As few times before, here are few discoveries from the Web:\nGoogle is pushing Internet Explorer 7. Their own version, using new Internet Explorer Administration Kit. It is not really different version - just configured with Google as default search engine and Google toolbar. Nothing that little more experienced user would not do himself. I am not sure how successfull this will be - but I am pretty sure that this was not what Microsoft had in mind how this tools should be used for.\n","title":"Weekend special","type":"post"},{"content":"It is this time of year - Christmas parties. It looks like the number of parties we go to every year increases - did not figure out yet which function it is, let's hope it is not exponential. This year, the number was four. First was traditional Christmas party at Peter's place. Second one - which I unfortunately missed - was a gettogether of Montage/Allstream alumni. I was sick and in bed - sorry I missed this one. Hope that there will be more opportunities for meeting during the long winter that is still ahead of us. Third party - \"the party\" - is Thinknostic Christmas Party, this year happening at Steve's place. And the party marathon will be closed by tomorrow's Tirestamp party at Sean's.\nLooking back on Thinknostic party, the growth is soo large. When we started in 2004, in was more like very private dinner of the founders and spouses. Party but not real party. The next year, the attendance was much bigger - somewhere around 20 people. Today, I expect more than double that count. If everybody who works with us would attend, we would be getting to closer to like 60. This is some number !\nNot only our party has this large positive gradient. During last 2 years, Tirestamp parties had been showing similar symptoms: from the small group of engineers, developers plus Scott, the company has grown and matured significantly. Should all the people attend (inclusive the US operations), I guess Sean would need bigger house (not that his current residence any small, quite the opposite).\nAnd because saying Merry Christmas in not politically correct, here is something more acceptable (do not know the source, friend emailed it to me few years ago):\nPlease accept with no obligation, implied or implicit, my best wishes for an environmentally conscious, socially responsible, low-stress, non-addictive, gender-neutral celebration of the winter solstice holiday, practiced within the most enjoyable traditions of the religious persuasion of your choice, or secular practices of your choice, with respect for the religious/secular persuasions and/or traditions of others, or their choice not to practice religious or secular traditions at all.\nAnd a fiscally successful, personally fulfilling, and medically uncomplicated recognition of the onset of the generally accepted calendar year 2005, but not without due respect for the calendars of choice of other cultures whose contributions to society have helped make this country great (not to imply that North America is necessarily greater than any other region or is the only \"America\" in the Western hemisphere), and without regard to the race, creed, colour, age, physical ability, religious faith, gender or sexual orientation of the wishee.\nThis wish is limited to the customary and usual good tidings for a period of one year, or until the issuance of a subsequent holiday greeting, whichever comes first. \"Holiday\" is not intended to, nor shall it be considered, limited to the usual Judeo-Christian celebrations or observances, or to such activities of any organized or ad hoc religious community, group, individual, or belief (or lack thereof).\nNote: By accepting this greeting, you are accepting these terms. This greeting is subject to clarification or withdrawal and is revocable at the sole discretion of the wisher at any time, for any reason or for no reason at all. This greeting is freely transferable with no alteration to the original greeting. This greeting implies no promise by the wisher to actually implement any of the wishes for the wishee her/himself or others, or responsibility for the consequences which may arise from the implementation or non-implementation of same.\nThis greeting is void where prohibited by law.\nHave a great HOLIDAY and an awesome NEW YEAR!\n","date":"December 15, 2006","externalUrl":null,"permalink":"/posts/2006-12-15-party-time/","section":"Posts","summary":"It is this time of year - Christmas parties. It looks like the number of parties we go to every year increases - did not figure out yet which function it is, let's hope it is not exponential. This year, the number was four. First was traditional Christmas party at Peter's place. Second one - which I unfortunately missed - was a gettogether of Montage/Allstream alumni. I was sick and in bed - sorry I missed this one. Hope that there will be more opportunities for meeting during the long winter that is still ahead of us. Third party - \"the party\" - is Thinknostic Christmas Party, this year happening at Steve's place. And the party marathon will be closed by tomorrow's Tirestamp party at Sean's.\n","title":"Party time","type":"post"},{"content":"Thought of the day:\n... Too much to learn. Too much bandwidth crowding the channels of communication. We can’t listen fast enough. We’re left standing on our tiptoes all the time\nGreg Bear, The Darwin's Radio\nThis does not sound very optimistic, which is quite representative. I am down with bad headache, cannot really think straight, spending time sleeping, reading a book (above) and surfing the Web.\nI found out that I made it to Ottawa Blogger's list and learned a new word: splogger\n","date":"December 14, 2006","externalUrl":null,"permalink":"/posts/2006-12-14-quote-of-the-day-2/","section":"Posts","summary":"Thought of the day:\n... Too much to learn. Too much bandwidth crowding the channels of communication. We can’t listen fast enough. We’re left standing on our tiptoes all the time\nGreg Bear, The Darwin's Radio\nThis does not sound very optimistic, which is quite representative. I am down with bad headache, cannot really think straight, spending time sleeping, reading a book (above) and surfing the Web.\nI found out that I made it to Ottawa Blogger's list and learned a new word: splogger\n","title":"Quote of the day","type":"post"},{"content":"","date":"December 13, 2006","externalUrl":null,"permalink":"/tags/microsoft/","section":"Tags","summary":"","title":"Microsoft\"","type":"tags"},{"content":"As I mentioned yesterday, my expectations regarding Office 2007 were fairly low. I am not a big fan of office application suites and for most of my editing I am using either on-line tools (like Google docs or Writeboard) or Open Office. True, neither of them has the smoothness and fine polish of Microsoft Office 2003, neither has all of it's features, but - let's face it - I barely use maybe 10-20% of Word or Excel capabilities anyway. For which reason, I am not willing to pay premium just for improved user comfort.\nMost people see the new, good looking Ribbon UI of Office package and user interaction as the most important improvement. This is certainly an improvement, but what was nice surprise for me was a look under the hood. It was no secret that the new file format is XML based. Which does not say much, because there are many ways how to store anything in XML, including very many very bad ways. What Microsoft did, however was really nice: every file in new format is ZIP-ped folder (with extension e.g. .docx instead .zip). Within this folder exists a hierarchy of XML files and subfolders. Very clean and very efficient. If you for example add an image to Word document, rather than mangling the JPG and merging it into tasteless binary blob with the rest of even uglier binary blob (as Word 2003/XP/2000/97 etc would do), it is stored as exactly the same, standard binary JPG file inside subfolder 'media' and referred from xml data file.\nThis structure saves space, because XML compresses very very well and allows access to document's data on any platform by any language as long as it can parse XML. Hallelujah ! Finally an easy and elegant way how to access office documents from Java or Python, without going through libraries such as POI (which is a Java libary to access binary OLE2 based documents) based on reverse engineering undocumented formats. Btw, POI stands for Poor Obfuscation Implementation :-).\nNot only it is now possible to generate and parse office documents on server side much easier, on non-Windows platforms (e.g. Java on Solaris), it actually helps to do the job for the Windows servers as well. If you ever tried to do anything with Office documents on server side, you must have found out using Windows server does not help you much: you cannot use COM wrappers around Office installation on server anyway. Not only because on the server side, there would be nobody to listen to the poor paperclip ... but because multithreading capabilities of office libraries and COM wrappers around them are fairly limited for any number of threads large than two ...\nAnother very nice feature is separate storage of document itself and document form data. If you have a form in Word document with fields to be filled in by user, you can lock the form so that only content of the fields can be edited. When user saves such document after filling the form out, the data entered is actually stored in different XML file. Very useful - this is very nice alternative to user editable PDF forms. I can imagine lot's of applications in public sector.\nAlso macros and active content (scripts) can be now much nicer separated. Unfortunately, the VBA is still alive ... but at least it is now visible, not hidden. This may be important to identify and control VBA viruses and Malware.\nThanks to these changes, Office is suddenly interesting platform for business solutions. Both programming \"from within of Office\" by modifying the Office UI by script inside the document and \"from outside of Office\" - using Visual Studio Tools for Office is now easier and cleaner. In addition, you can now use \"without Office\" by accessing the data directly, on machine without Office installed using excellent .NET XML capabilities, or even without Windows, going with Java, Python, Perl, Ruby, Javascript - you name it.\nOne final observation from the developer's sessions (while talking about RSS): It is great that there is improved support for RSS in .NET 3.0, we all liked it a lot. What I personally liked much less was that small remark in presentation:\n... we at Microsoft have implemented and enhanced the RSS standard. Let's get one thing straight: the only thing that can be done with a standard is follow it, implement it and keep it unmodified. Enhancing standard means breaking it, guys! If you really want to have standard that is your own, create one from scratch and convince the world to follow you. Taking something that is out there, and turning it by proprietary enhancements into something new is not what innovation is suppose to be. And certainly not an improvement.\n","date":"December 13, 2006","externalUrl":null,"permalink":"/posts/2006-12-13-ready-for-a-new-day-continued/","section":"Posts","summary":"As I mentioned yesterday, my expectations regarding Office 2007 were fairly low. I am not a big fan of office application suites and for most of my editing I am using either on-line tools (like Google docs or Writeboard) or Open Office. True, neither of them has the smoothness and fine polish of Microsoft Office 2003, neither has all of it's features, but - let's face it - I barely use maybe 10-20% of Word or Excel capabilities anyway. For which reason, I am not willing to pay premium just for improved user comfort.\n","title":"Ready for a new day (continued)","type":"post"},{"content":"Today was a big day in Ottawa Microsoft community. The Congress Centre was hosting large event - simultaneous launch of Windows Vista, Office 2007 and Exchange server 2007. Because I have almost registered about two months ago, I attended the event. The \"almost\" means that I tried to register right after receiving MSDN Flash email, but many people must have been faster - I was put on waiting list on two of the 3 tracks (Developers and IT Pros) and before I could even try to register for the third track (Business), everything crashed, Web site hang and I have never heard back from them, nor received any email. Until yesterday, when an automated voice reminder service managed to catch me by phone in underground garage under Brookstreet Hotel, and delivered first part of reminder - telling me that I was registered to attend something ... Too bad it did not tell me to what, when and where did I registered, before it broke off and I lost the signal. But I deducted that the only reason to call me would be a reminder of the Launch and after logging on to My Events, voila - the ticket was there. So I went. It was a tough decision, whether to sacrifice full work day and possibly evening ping-pong at Igor's - but - what the heck. Microsoft does not produce new releases that often so going away once in 5 years should be OK. And now I am glad I did go.\nMy attitude in the Tuesday morning was: I am really curious about Vista from developer's point of view, I do not care at all about new Office (who needs another version, Office 2003 is an overkill and besides we have Google docs and OpenOffice) and certainly not about Exchange. Well, I think different about two of the three topics above right now - but let's keep the sequence.\nIt was nice change to take bus to downtown for a change, after daily driving to Kanata. The location was Ottawa Congress Centre, conveniently attached to Rideau Shopping Centre. The attendance was huge - I guess there must have been well over 1000 people. It was well organized and everything went very smoothly and professionally - as far as logistic is concerned.\nThe show started with a keynote delivered by the president of Microsoft Canada. I have visited few similar venues, and I must tell this was probably the most uninteresting and uninspiring keynote I have seen so far. It lacked spirit, personality, leadership, charisma - everything that I was expecting from a leader representing company of Microsoft's calibre. Maybe I had too high expectations, after seeing (recorded) keynotes of Steve Jobs from last year MacWorld and WWDC - but even the keynotes at the few Ottawa Linux conferences I have attended in the past (I stopped after 2002) were much more interesting. For any other company, the keynote would probably do. But with Microsoft, one cannot have just a lukewarm, i-do-not-care opinion: people either like them a lot or dislike them a lot. Or both at the same time.\nThere were actually two speakers and two guests within the keynote. While the main part was not exactly exciting, the second part, delivered the economist and writer Michael Treacy - an author of Double Digit Growth IMHO completely missed target. He tried to provide high level view on outsourcing, new trends in markets and importance of productivity.\nNot that the lesson on importance of knowledge in digital economy was incorrect - but it did not fit well with the audience. Certainly not with the group around me. The comments overheard were like: \".. this sounds like Economy 101 at Carleton .. wait, it's more like second year \". To me, it sounded like fairly incomplete attempt to deliver the key message of Thomas Friedmann's book The World Is Flat without mentioning Netscape, Yahoo, OpenSource and Google :-). The book is great - read it (I mean Friedmann's book, did not read the other one). Besides, several claims made during the keynote were tough to digest: what are the data supporting the fact that Ireland has highest living standard in Europe ? What were the indicators used to measure it ? I guess that Swiss, Danes, Norwegians (and other Scandinavians) may quite disagree with that ...\nA funny little thing: one of the keynote speakers (cannot remember who) was mentioning the Vista new features and used by mistake Apple's name for the desktop \"components\" which are called widgets in OS-X (and accessible by using F12) rather the proper Vista term gadgets. Yes, we know: gadgets / widgets - completely different, and the new Vista Aqua look is really great, oops, I meant Aero.\nFortunately, the technical sessions were good and I have learned more than I have expected. The presenters were as usual strong and the demo's were reasonably well prepared with few hickups.\nIf I compare this event with the Visual Studio 2005 Launch or with Win2003 introduction, I think there was noticeable change of atmosphere. Somehow the excitement was down, the tone was more like \"we are big and serious company, not group of techies\", and generally there was much less \"wow\" and much more \"ok, ok - so what\". Was it because of the different audience ? Was it because of the people were tired waiting 5 years for Vista ? Was it because the scaled down (where is WinFS!!), catching-up-with-Mac (gadgets, Aero, search, ....) featureset of Vista ? Or because Microsoft itself became different company than it was, with Bill Gates stepping down as the icon and leader, being replaced by who-the-heck-is-that-guy-name ? No disrespect Mr. Next Chief Architect, but nobody can really replace such a legend as Bill Gates.\nAnyway, back to presentations. I sat on developer's track and as I said, they were good and interesting. Thanks, Christian and Jean-Luc, you were great as usual. The only remark: please stop that silliness with shouting \"Developer Rocks!\" really loud so that business group hears us. It is pretty lame and very juvenile. Just because your boss likes to shout Developers! really loud, you do not have to. Fortunately, we were not asked to do monkey dance either :-).\nFirst and most expected product launch was certainly Vista. When companies finish and release large product, they like to do pizza parties. Considering amount of time and money that were invested to Vista, Microsoft should probably have rented Hawai back in November when Vista went gold (as somebody on TWIT suggested).\nAs a user, what I like about Vista is that it will over time improve security situation on the Net. Built in malware and spyware detection, better security, standard user accounts as defaults (not admin), kernel patch protection are certainly steps in right direction. Compared to introduction of Windows XP, with Vista, Internet will be better place, as soon as the bugs are hunted down to acceptable numbers.\nWhat I do not like is that for certain amount of time, Vista may make security situation worse: the network stack is new and can contain lots of security problems (listen to Security Now on Vista Virgin Stack). What I also do not like is hardware requirements. Come on, guys! It is true that we do have now dual core machine and 1 GB RAM as standard, with 3D accelerator's card. But the reason why people do buy these terrific machines is to run software that actually *does* something useful, and not just to happily let the operating system itself consume most of the RAM and CPU power just in order to run ... Just because users do have lots of RAM and several CPU cores, you do not have to feel an obligation to utilize them and keep them busy - just let them sit idle, there is nothing wrong with that.\nAs developer, I liked the new additions such as .NET 3.0, WPF, WCF, Workflow and Cards. I am little bit worried about how will the memory consumption and CPU load of XAML-ized apps look like - the demos I saw were routinely allocating few hundred MB of RAM and 80% of CPU cycles just to run simple Winform apps, but that was Beta version of everything. Let's hope the final version is better. I may have misunderstand the message, but most of the new features for developers will be available for XP and Win2003 platforms as well (maybe except some fancy GUI tricks). I certainly hope it will, because otherwise it makes little sense to use these features sooner than Vista penetration of the Windows market will not be at least 30-40%. Which will take some time.\nTo sum it up: I have not really used Vista long enough to have qualified opinions, but so far have mixed feelings. I guess it is OK, looks nicer than XP, is comparable to OS-X (some features are better, some are worse) but I am not overly ecstatic about it. I have not seen any features that would make me feel \"I must have that\" - unlike Leopard with TimeMachine. For example, the search in Vista seems to be using old \"indexing service\" approach and will be very likely considerably slower and less usable than Spotlight for 100 GB+ volumes of data. Vista certainly is important release and we will jump on it, but not right away there is no rush and no urge to upgrade. The XP and Win2003 will do for now. At least they run OK in Parallels :-).\nUnlike Vista, I have changed (and much improved) my opinion about Office 2007. But that is for tomorow.\nWill be continued\n","date":"December 12, 2006","externalUrl":null,"permalink":"/posts/2006-12-12-ready-for-a-new-day-or-vista-office-exchange-launch/","section":"Posts","summary":"Today was a big day in Ottawa Microsoft community. The Congress Centre was hosting large event - simultaneous launch of Windows Vista, Office 2007 and Exchange server 2007. Because I have almost registered about two months ago, I attended the event. The \"almost\" means that I tried to register right after receiving MSDN Flash email, but many people must have been faster - I was put on waiting list on two of the 3 tracks (Developers and IT Pros) and before I could even try to register for the third track (Business), everything crashed, Web site hang and I have never heard back from them, nor received any email. Until yesterday, when an automated voice reminder service managed to catch me by phone in underground garage under Brookstreet Hotel, and delivered first part of reminder - telling me that I was registered to attend something ... Too bad it did not tell me to what, when and where did I registered, before it broke off and I lost the signal. But I deducted that the only reason to call me would be a reminder of the Launch and after logging on to My Events, voila - the ticket was there. So I went. It was a tough decision, whether to sacrifice full work day and possibly evening ping-pong at Igor's - but - what the heck. Microsoft does not produce new releases that often so going away once in 5 years should be OK. And now I am glad I did go.\n","title":"Ready for a new day - or Vista-Office-Exchange launch","type":"post"},{"content":"My daughter's music CD for her skating short program got badly scratched and because it was the last-but-one copy (as skater you need many copies, in case you loose/forget/scratch/misplace it), I was confronted with the task to create a new copy. Rather than starting Nero on Win-XP notebook, I have decided to learn (finally) how to do it on Mac. It must be simple, intuititive and much easier than on Windows. Right ? Wrong ! To my big surprise, there was no easy, idiot proof, very obvious way mac-ish drag and drop way how to acomplish it. It was not exactly hard either, but it actually took consulting the omniviscent Google to find it out. To save the search for the next time, I'll write it down. Here is what you have to do:\n1) Create a disk image from source CD\nInsert the source CD (the one you want to copy) Open the Finder, open Applications, then Utilities, and start the Disk Utility program In Disk Utility, select File -\u0026gt; New -\u0026gt; Disk Image from Folder The Finder will appear - select whole CD and click on the Image button A new dialog box will appear. In the Where box, choose Desktop. In the Image Format box, choose DVD/CD master Click Save Now a new file will be created on your Desktop, titled the name of your CD with a \".cdr\" extension. This file is a disk image of your CD. Btw, it works even if you do not select cdr format and write disk as generic Disk Image (.dmg).\nNow you need to burn it on new, blank CD:\n2) Create new CD from a disk image\nEject your original CD from the CD drive Return to the Disk Utility program. You should now see the disk image of your CD on the left hand side, typically at the bottom of the list. Select the image, and then click on the Burn button Follow the directions and insert a black CD-R disc when prompted You can repeat step 2 as many time you need, of course :-). Next time I am going to use the image, of course assumed that it will be still the same music. Thanks to Spotlight magic, I am sure I will be able to find it, because I used proper, descriptive and obvious name \"track 86.cdr\". Just kidding :-).\nWhat do you think - why did not Apple make this process easier - as they did for many other chores ? Has it maybe anything to do with the fact that copying CD can be (and quite often is) used for copyright violation activities ?\n","date":"December 11, 2006","externalUrl":null,"permalink":"/posts/2006-12-11-how-to-duplicate-cd-on-a-mac/","section":"Posts","summary":"My daughter's music CD for her skating short program got badly scratched and because it was the last-but-one copy (as skater you need many copies, in case you loose/forget/scratch/misplace it), I was confronted with the task to create a new copy. Rather than starting Nero on Win-XP notebook, I have decided to learn (finally) how to do it on Mac. It must be simple, intuititive and much easier than on Windows. Right ? Wrong ! To my big surprise, there was no easy, idiot proof, very obvious way mac-ish drag and drop way how to acomplish it. It was not exactly hard either, but it actually took consulting the omniviscent Google to find it out. To save the search for the next time, I'll write it down. Here is what you have to do:\n","title":"How to duplicate CD on a Mac","type":"post"},{"content":"Yes, I know, the title sounds like oxymoron and to certain degree, it is. What it should maybe say is Person who should have been celebrity ...\nI am not going anywere close to movies or entertainment industry with this. There are more than enough sites, blogs and gossip channels out there that look at life of movie stars or singers. I will stay within the world of computers and technology, which has its own heros and celebrities, albeit known in smaller groups. In \"real world\", pretty much everybody knows Bill Gates, Linus Torvalds, Steve Jobs, Larry Ellison, Steve Wozniak. They have made the headlines many times. Fewer people know names like James Gosling, Anders Hejlsberg, Bill Joy, Dennis Ritchie, Guido van Rossum, Guy L. Steele, Richard Stallman....\nStrangely enough, there is a name in history of human-computer interaction and computer technology that is associated with such significant advances as graphical user interface, networking, groupware and internet. This man personally invented computer mouse in 1967 and his team developed hypertext, whose most famous implementation is World Wide Web.\nHis name is Douglas Engelbart, and he is still working - in his 81 years, as the director of his own company, the Bootstrap Institute. He never made any money on his mouse invention - the patent expired before the personal computers and GUI made the mouse ubiquitous. At least, his company is housed rent-free courtesy of the Logitech Corp., company which made lots of many on computer mice manufacturing. Nice gesture, Logitech - I will keep buying your products :-).\n","date":"December 10, 2006","externalUrl":null,"permalink":"/posts/2006-12-10-unknown-celebrity/","section":"Posts","summary":"Yes, I know, the title sounds like oxymoron and to certain degree, it is. What it should maybe say is Person who should have been celebrity ...\nI am not going anywere close to movies or entertainment industry with this. There are more than enough sites, blogs and gossip channels out there that look at life of movie stars or singers. I will stay within the world of computers and technology, which has its own heros and celebrities, albeit known in smaller groups. In \"real world\", pretty much everybody knows Bill Gates, Linus Torvalds, Steve Jobs, Larry Ellison, Steve Wozniak. They have made the headlines many times. Fewer people know names like James Gosling, Anders Hejlsberg, Bill Joy, Dennis Ritchie, Guido van Rossum, Guy L. Steele, Richard Stallman....\n","title":"Unknown celebrity","type":"post"},{"content":"According Forrester reseach \".. the Web will fade. It will be replaced by a new software paradigm\". Nobody knows what this new paradigm will be, but these guys are saying that it will be their platform. I found this link from this very interesting two part article Changing Climates for Microsoft and Google, Desktops and Webs making interesting analogy between Google and AOL business model, browser as a platform and possible return of thick client (\"smart client\" in Microsoft terms), why Google might want to buy Adobe and many other interesting observations. Worth reading.\nThis blog contains tons of interesting information about Mail app functionality. Very interesting (if you have Mac).\nLibrary thing is fascinating site about books - it searches Amazon, the Library of Congress and 60 other world libraries and allows browse informations about books, authors , organizing books, making your own collections and following suggestions - \"if you liked this book, you may like these as well\" type of thing. A very nice idea are also \"unsuggestions\" - if you liked X you will hate Y. For example, if you liked \"The code book\" by Simon Singh (as I certainly did), you will hate The Pilots Wife and about 25 other books. Cannot confirm - I have not read any of them :-)\nInteresting article on synchronization between Outlook, GMail and iPod - something I need spend some time thinking about soon.\n","date":"December 9, 2006","externalUrl":null,"permalink":"/posts/2006-12-09-few-new-links-from-my-delicious-collection/","section":"Posts","summary":"According Forrester reseach \".. the Web will fade. It will be replaced by a new software paradigm\". Nobody knows what this new paradigm will be, but these guys are saying that it will be their platform. I found this link from this very interesting two part article Changing Climates for Microsoft and Google, Desktops and Webs making interesting analogy between Google and AOL business model, browser as a platform and possible return of thick client (\"smart client\" in Microsoft terms), why Google might want to buy Adobe and many other interesting observations. Worth reading.\n","title":"Few new links from my del.icio.us collection","type":"post"},{"content":"http://manybooks.net/. 'nough said.\n","date":"December 8, 2006","externalUrl":null,"permalink":"/posts/2006-12-08-too-many-ebooks-too-little-time/","section":"Posts","summary":"http://manybooks.net/. 'nough said.\n","title":"Too many ebooks, too little time","type":"post"},{"content":"I have switched away from using Outlook once again for variety of reasons - as part of my latest attempts to reduce complexity and increase security (more on that later) and went back to Thunderbird/Web based email systems on all Windows machines. Conversion of address books was piece of cake this time, thanks to Plaxo which I use to synchronize Mac and Windows based systems. Nonetheless, I got curious what format does Thunderbird use for address book and this way I have discovered the awkward Mork file format.\nTypical way how to process this is using Perl or Python. Jamie Zawinski wrote one of the scripts in Perl. I normally do not consider reading Perl code to be my favorite leisure time activity (we all know that Perl is write-only language), but this time I did peek in. Here is pure jewel I have discovered inside:\nSee the whole script. Who said that reading Perl script cannot be fun ?\nBtw, if you are using Windows (which does not have the wonderful snapshot capabilities of Command-Shift-3/Command-Shift-4 keys), you may find Cropper very useful. It is free, opensource and works like charm. Requires .NET framework, but that's pretty much everywhere. Enjoy\n","date":"December 7, 2006","externalUrl":null,"permalink":"/posts/2006-12-07-reading-code-can-be-fun/","section":"Posts","summary":"I have switched away from using Outlook once again for variety of reasons - as part of my latest attempts to reduce complexity and increase security (more on that later) and went back to Thunderbird/Web based email systems on all Windows machines. Conversion of address books was piece of cake this time, thanks to Plaxo which I use to synchronize Mac and Windows based systems. Nonetheless, I got curious what format does Thunderbird use for address book and this way I have discovered the awkward Mork file format.\n","title":"Reading code can be fun","type":"post"},{"content":"Today's extension is from the area of - surprise surprise - security and privacy. I guess I am getting slightly paranoid from all the security related stuff I am listening to. But I promise I will switch back to \"standard\" TWIT, MacBreak and Windows Weekly to compensate the security heavy topics. But it certainly true that the more you are aware of what is technically possible, the more hostile Internet you will see ...\nThe extension name is Stealther and it can help you surf the web without leaving a trace in your local computer. What it does is temporarily disable the following:\nBrowsing History (also in Address bar) Cookies Downloaded Files History Disk Cache Saved Form Information Sending of ReferrerHeader In other words, with Stealther on, you can visit dubious sites without leaving traces on your local computer - this is the key. It is important to understand what it does NOT do because people sometimes get false feeling of security when using tool like this. Even with Stealther on,\nRemote site still will know your external IP address you will be vulnerable to all exploits to the degree your browser is vulnerable (with Firefox, you will be much better of than with IE version \u0026lt;= 6, but not really secure full history of your interaction with the site can be recorded at the site or at your ISP Simple experiment can visualize what exactly is the difference between surfing with and without Stealther: using the LiveHTTPHeader extension, let's click a link 'Firefox Help and add ons' on Firefox default start page and compare the difference. Here is the HTTP request without Stealther (ignore the line numbers, they are from Smultron):\nand here is same request with Steather on:\nWhat is missing is the Referrer link - the foreign site will not know where you came from. Which may or may not be important. Other than that - the site will still get all information about your browser version and OS, which can be used (in case of malicious Web site) to render page that will try install spyware or virus or benefit from known browser exploits.\nDespite of that, Stealther is very useful to control cookies. In Firefox, you can set option that every attempt to set cookie can be examined and manually confirmed. If you decide to do that, you must have a patience of a saint, because browsing will become very annoying sequence of deciding whether you allow or disallow cookies. With Stealher, you can keep your browser setting on less draconian (and more practical) level and activate \"cookie killer\" on request, whenever you will enter zone of aggressive sites that may try to trace your digital pathways.\nStealther does pretty decent job in covering your trails on local computer side. It is very small, fast and non-intrusive. Of course, if you want *really* to be sure you have not forgotten anything, the best way is to install Linux in virtual machine with Firefox browser, surf from the VM environment and throw the virtual disk away after you are done. Do not forget to use few anonymizing proxies (ideally located in different countries) and start your surf from public anonymous internet location like Bridgehead . Hush hush ...\n","date":"December 6, 2006","externalUrl":null,"permalink":"/posts/2006-12-06-feotd-stealther/","section":"Posts","summary":"Today's extension is from the area of - surprise surprise - security and privacy. I guess I am getting slightly paranoid from all the security related stuff I am listening to. But I promise I will switch back to \"standard\" TWIT, MacBreak and Windows Weekly to compensate the security heavy topics. But it certainly true that the more you are aware of what is technically possible, the more hostile Internet you will see ...\n","title":"FEOTD: Stealther","type":"post"},{"content":"I have worked through my listening to the Security Now! podcasts up to middle October now (more specifically up to here) and one remark from Steve Gibson forced me to think very hard: how today's hard drives encounter hundreds of read errors a day (actually Leo said \"hundreds a minute\"), but thanks to ECC process and dynamic reallocation of sectors, this is invisible to the user, because:\n\" .... if a file is damaged because of a bad sector, it can recover that data by recovering the data, either moving it or kind of reformatting the sector underneath it to make it readable again ... \"\nas well as\n\" Drives have gotten so dense that drives are now depending upon the error correction code, ECC, just to read good sectors, not even bad sectors....\"\nThis made me really worried. I was deciding right now to buy the RAID-5 NAS storage (1 TB or 2 TB), because I always considered hard drive the most reliable storage medium: better than DVD and much better than very unreliable CDR (which are unreasonably small anyway). My line of thinking was: I want to get as large disks as I can within the budget.\nThe trend of increasing densities and decreasing the price of hard disks leads us \"probabilistic\" information storage. Imagining how my hard disks keep reallocating sectors and that the deliver data only because some correction codes works on fixing errors that occur every minute ... ouch. Despite of that, the hard drive manufactures keep offering 3 to 5 years warranties on most drives. This may look good in theory, but I do not really care that I will get back my $96 for the failed 250 GB hard disk. Loosing 250 GB of images and videos is a big deal. And the only way how to back up such amount of data in home environment - is to use another harddrive, unfortunately.\nMaybe trying to get as big hard disk as possible is not the smartest approach. The smallest hard disk one can buy these days is about 80 GB (~ $50) with the largest in range of 400-500 GB. What is the ideal ballance between size, price and reliability ? That's a very good question.\n","date":"December 5, 2006","externalUrl":null,"permalink":"/posts/2006-12-05-the-problem-with-hard-drives-too-large-and-too-cheap/","section":"Posts","summary":"I have worked through my listening to the Security Now! podcasts up to middle October now (more specifically up to here) and one remark from Steve Gibson forced me to think very hard: how today's hard drives encounter hundreds of read errors a day (actually Leo said \"hundreds a minute\"), but thanks to ECC process and dynamic reallocation of sectors, this is invisible to the user, because:\n\" .... if a file is damaged because of a bad sector, it can recover that data by recovering the data, either moving it or kind of reformatting the sector underneath it to make it readable again ... \"\n","title":"The problem with hard drives: too large and too cheap","type":"post"},{"content":"","date":"December 4, 2006","externalUrl":null,"permalink":"/tags/c-sharp/","section":"Tags","summary":"","title":"C-Sharp","type":"tags"},{"content":"It is now about 1 year since official release of C# 2.0 and .NET framework 2.0. The next version of C# language - the C# 3.0 seems to get more and more attention - in blogs, official channels and MSDN. There is lot of excitement and big expectations - but I have nagging feeling that the general direction of the C# development is not necessary an improvement.\nThe main new features of the C# 3.0 language are implicitly typed variables and anonymous types, extension methods, lambda expressions, and LINQ - possibility of using SQL-ish dialect inside the C#. With exception of the last, all of them must sound very familiar to every Python programmer. All variables in Python are implicitly typed, we can extend classes to much larger degree than extension methods and lambda expressions were always integral part of Python (inherited from Lisp and Scheme).\nFor several reasons, I believe that this is wrong. Strong typing and type safety is very important for every programming language that is suitable for building large and complicated systems - enterprise level applications. Allowing dynamic typing may be tempting, but what it does is moving discovery of errors from compilation time to runtime. There is nothing wrong with dynamic typing - Python, Perl and few others are great languages. Albeit there are large and complex systems written in Python (e.g. Zope), I think that \"classical\" strongly typed languages (Java, C#) still does result in more robust systems.\nAdding functional constructs such as lambda expressions and extension methods basically creates a hybrid functional-OO language, sort of a cat-dog. For seasoned Lisp programmer, even Python's support for functional programming is not good enough - and Python is internally much more dynamic language than C#: functions, classes and modules are first class objects (just compare the simplicity of event handling in Python with events and delegates). What value will it add to embedd some limited functional constructs to fairly traditional OO language as C# is ?\nThe project LINQ and mixing up SQL with C# in same source file is from my point of view worst idea of all C# 3.0 new features. It may sound great and be very helpful for small projects, but for enterprise size applications it makes so much easier to create complete mess in application architecture... Same thing happened few years ago with visual GUI building tools - people started to place lots of business logic into form event handlers - this is no problem for 3-4 screen mini app, but disaster for large and complex system, where you do want to have proper layers, roles and responsibilities and at minimum some form of MVC pattern. Again, there was nothing wrong with UI designers, it is just that they made doing incorrect thing so much easier ...\nThe problem of \"impedance mismatch\" between world of objects and world or relational tables is real and none of the solutions we have today is perfect and applicable everywhere: code generators (of either database or object layer), \"active\" datasets, business object frameworks, mappers and ORM layers. What they do give us, though, is modularization and separation of concerns which is very important for code maintainability and readability. Mixing everything together inside same class just does not sound right.\nVery important for success of programming language is simplicity and support for writing understandable and maintainable code. Somehow, both Java and C# seem to loose the original simple elegance of their origin. Adding generics in C# 2.0 and Java 5 was for me strange mixture of blessing and curse - yes, generics do help solve some type of problems in a very elegant way, but quite often lead to unexpected issues and complications elsewhere. Our recent adventures with CSLA framework are a very good illustration of this - but that's topic for another entry.\nNo programming language is perfect for every purpose. This is why we have so many of them. So if you want to have very dynamic language with functional programming support in .NET environment why not to use Python directly ? The .NET implementation IronPython is amazingly fast, compiles to CLR and works just fine. If you want very solid language for enterprise development on Microsoft operating system, there is absolutely nothing wrong with C# 2.0. There is no need to mix them together ...\nWhy do I suggest that C# would become uglier version of Python ? Because I believe it will look uglier to almost everybody. For somebody with strong traditional OO background and lots of strongly-typed languages history (some ex-Java, ex-ex-C++ programmer like myself), \"var i\" sounds too much like Visual Basic and extending class by method injection and not by inheritance is close to blasphemy. And for Python enthusiast, who enjoys dynamic features and scripting power of Python (like myself ;-)) all that stuff with data types and private/protected hide-and-seek games is just unnecessary ballast - not speaking about those terrible curly brackets, ouch ...\nBesides, if you *really* must do all the things above, how about using \"Object i\" instead \"var i\", injecting methods to classes by using Spring.NET (which can, btw do much cooler things thanks to AOP and dynamic proxies) and trying out something like iBatis.NET for making sure that your C# code and SQL code coexist peacefully ?\n","date":"December 4, 2006","externalUrl":null,"permalink":"/posts/2006-12-04-will-c-30-become-a-uglier-version-of-python/","section":"Posts","summary":"It is now about 1 year since official release of C# 2.0 and .NET framework 2.0. The next version of C# language - the C# 3.0 seems to get more and more attention - in blogs, official channels and MSDN. There is lot of excitement and big expectations - but I have nagging feeling that the general direction of the C# development is not necessary an improvement.\nThe main new features of the C# 3.0 language are implicitly typed variables and anonymous types, extension methods, lambda expressions, and LINQ - possibility of using SQL-ish dialect inside the C#. With exception of the last, all of them must sound very familiar to every Python programmer. All variables in Python are implicitly typed, we can extend classes to much larger degree than extension methods and lambda expressions were always integral part of Python (inherited from Lisp and Scheme).\n","title":"Will C# 3.0 become an uglier version of Python ?","type":"post"},{"content":"It's been almost 5 months now since I started to use Mac OS-X. During these months, I became very comfortable in the new environment and albeit I do not consider being a power user, I can do all I need with my Macbook and use it daily.\nToday I found out that yet another from my friends got a Mac. Great news, Thomas - hope you will enjoy your Macbook Pro as much as myself, Gabo and many others. Welcome in the club.\nAs promissed, here is a quick list of the software I found useful.\nNeoOffice - Cocoa port of OpenOffice. All you need to interoperate with business world - excellent compatibility with Microsoft office formats. I had never any issues reading Word, Excel or PowerPoint documents from Windows. We use OpenOffice in business since September and it works really fine. NeoOffice uses same engine, but user interface is not based on X-Windows (as it would be for Linux and other Unix distribution), but is Mac native. Free, GPL, great looking and works like charm. Highly recommended.\nAdium - free instant messaging application for Mac OS X that can connect to AIM, MSN, Jabber, Yahoo. No voice chat available (yet).\nCHmox - http://chmox.sourceforge.net/ - native viewer for CHM format (Microsoft Compiled Help) for OS-X. Mission critical app for eBook fans. Not sure if it is the typography, but even MSDN Magazine looks so much nicer on Mac :-)\nAquamacs Emacs - \"the Allmighty Editor\"in Aqua version. 'nough said.\nCocoalicious - offline client for del.icio.us. Usefull for backup purposes of the bookmarks.\nCoRD - Remote Desktop Client to access Windows machines from Mac\nDelicious Library - book and DVD management program. Not free, but worth every penny - fantastic!\niTerm - very nice terminal\nLibrary Books - menulet that reminds me to return books to local library.\nMacTheRipper - nice DVD tool :-)\nPalmDocConverter - converts PalmDoc format to text (another eBook maniacs must-have)\nQuickSilver - Hard to describe in one sentence, but very useful. Officially, it is a launcher. In reality, more like Swiss Army Chainsaw :-)\nSmultron - small and nice text editor with support for syntax colouring\nViewIt - image viewer\nThunderBird - email client, if Mail is not good enough (which IMHO is).\nVLC - media player\nWikiNotes - personal desktop Wiki\nWriteroom - perfect editor to eliminate distraction and focus on the content\nXFolders - NortonCommander reincarnated in Aqua (recommended by Apple)\nMPEG StreamClip - A converter for MPEG-1/2/4, QuickTime files\nJournler - journaling software, for the stuff unsuitable for Blog.\nFish - virtual aquarium simulator, see the world thorugh the eyes of fish\nSolitaire - most used business application for Windows, only nicer\nEnjoy !\n","date":"December 3, 2006","externalUrl":null,"permalink":"/posts/2006-12-03-software-for-new-mac-users/","section":"Posts","summary":"It's been almost 5 months now since I started to use Mac OS-X. During these months, I became very comfortable in the new environment and albeit I do not consider being a power user, I can do all I need with my Macbook and use it daily.\nToday I found out that yet another from my friends got a Mac. Great news, Thomas - hope you will enjoy your Macbook Pro as much as myself, Gabo and many others. Welcome in the club.\n","title":"Software for new Mac users","type":"post"},{"content":"After listening for over week to Security Now! podcast (thanks, Steve, thanks Leo and happy birthday), I've decided to actually do something about the security on computers around. I started to scanning my home network using \"Shields Up\" and was happy to found that the only open port was SSH, exactly as I thought I configured it.\nAs next step, I followed the advice from this podcast and used my hosts file to block out ads servers and other internet vermins. You may also want to look at the podcast notes, read full transcript or listen to it.\nI have downloaded the public hosts file, containing over 12 thousands entries and merged it with my own hosts file. Because I am running Web server on every computer I use (to be able to develop web applications), I have replaced the loopback to 127.0.0.1 with 0.0.0.0 in all entries (except for localhost, of course). The 0.0.0.0 is invalid address and will cause that the request will be dropped immediatelly, rather that trying to reach destination. If you are not running web server, the 127.0.0.1 will work just fine. Do not get scared with the file size - Windows can scan through the entries really quickly and it is always by order of magnitude faster than try to do any network connection. Guarranteed ! Btw, Wikipedia has pretty good entry on hosts file.\nAs third, I started to use 10 minutes email for sites that require my email address to register (and potentially spam me). The idea is simple: you go to the web page, generate for yourself temporary email address that will live for 10 minutes. Any e-mails sent to that address will show up automatically on the web page. You can read them, click on links, and even reply to them. The e-mail address will expire after 10 minutes. You can extend the life for another 10 minutes if you need to. Simple, effective, free. There are many other providers of this service (see e.g. this list) but some of them require you to register first, which IMHO beats the purpose: in order to avoid providing your email, you have to provide your email first :-). The 10minute mail works without this nonsense. Hope it will stay alive\nFew more quick finds from Web:\n- See the some examples of non-standard and creative 404 pages: 1, 2, 3, 4\n- if you are male AND software developer, this is rather non-standard characterization of programming languages\n- interesting torrent search site\n- here is what will happen when you try to download the whole internet\n- nice article on pragmatic agile approach summary (which I wholeheartedly agree with) by Jeremy Palermo\n","date":"December 2, 2006","externalUrl":null,"permalink":"/posts/2006-12-02-security-now/","section":"Posts","summary":"After listening for over week to Security Now! podcast (thanks, Steve, thanks Leo and happy birthday), I've decided to actually do something about the security on computers around. I started to scanning my home network using \"Shields Up\" and was happy to found that the only open port was SSH, exactly as I thought I configured it.\nAs next step, I followed the advice from this podcast and used my hosts file to block out ads servers and other internet vermins. You may also want to look at the podcast notes, read full transcript or listen to it.\n","title":"Security now","type":"post"},{"content":"Today's extension is yet another one that somehow works with URL's aka links. If you now have strange feeling that all extensions in last few days *were* about links, you are right. But realize that links are the most crucial feature of the Web, and therefore extensions dealing with links are really useful.\nAfter you download Linky (the download is very small - only 32 kB), it adds few entries into your context menu. How many new menu entries are added can be configured in plugin option. On activation, Linky shows you number of links and image links (URL pointing to picture) on currently page displayed page and allows you to open links in new tabs or new windows or open image links in new tabs or windows. In both cases, Linky displays dialog window with all links and allows individual selection of which links will be included.\nIf you before right-clicking on page (or Ctrl-Click if you are on Mac) select part of page, you can perform all actions mentioned above with links contained in selection. Linky also allows opening links that are not really links - the text links - but if you use Linkify plugin, you will never see these. Very nice feature is also opening all images from page (or selection) in single new window or single new tab.\nLinky is extremly useful on sites that maintain links - for example del.icio.us, digg or google . You fist select set of links by selecting the tags of interest and then open all links in tabs. While you read one tab, others are loaded in background. This is extremly efficient \"wide surfing\" which is very handy when you need to revies large amount of information without getting lost or distracted ... The only downside is memory consumption.\nAnd now for something completely different: I visited Steve Gibson's site and tried his very handy, free online security service. If you believe that your system or network is secure - verify it by visiting his site grc.com and checking whether your network shields are indeed up.\n","date":"December 1, 2006","externalUrl":null,"permalink":"/posts/2006-12-01-feotd-linky/","section":"Posts","summary":"Today's extension is yet another one that somehow works with URL's aka links. If you now have strange feeling that all extensions in last few days *were* about links, you are right. But realize that links are the most crucial feature of the Web, and therefore extensions dealing with links are really useful.\nAfter you download Linky (the download is very small - only 32 kB), it adds few entries into your context menu. How many new menu entries are added can be configured in plugin option. On activation, Linky shows you number of links and image links (URL pointing to picture) on currently page displayed page and allows you to open links in new tabs or new windows or open image links in new tabs or windows. In both cases, Linky displays dialog window with all links and allows individual selection of which links will be included.\n","title":"FEOTD: Linky","type":"post"},{"content":"I have read somewhere that quotation is safe way how to say something potentially dangerous or controversial without being legally exposed :-). So today I am going to quote an authority in computer security - Steve Gibson on some very interesting Vista related security information.\nSteve is doing (together with Leo Laporte) excellent weekly podcast \"Security Now!\". It is so great that I have decided to download as many back episodes as I could find on their site and started to listen to them in the chronological order, back from June 2006. It was worth of every minute. I am now somewhere in August 2006 and Steve Gibson (== SG) covered interesting tricks what to do with you hosts file, very nicely explained the usefulness of netstat program and started multi-episode sequence on virtualization and virtaul machines. Thanks to many years of experience, Steve always gives a historical perspective on every topic he covers.\nWhat I want to mention (and quote) is the Vista security and Microsoft claims that\na) Vista is the most secure Windows system ever written and much more secure than previous versions of Windows\nb) the Vista code was written from scratch which should be in support and a contribution to a)\nAs SG said, security is something that is earned, not claimed. No company can say that system XYZ is most secure - it can just release it and let the reality - how the system stands in hard battles of attacks - decide how secure or insecure the system is. For that reason, according to SG, saying anything about Vista security is at minimum premature - and nothing really new, because similar claims were made with release of Windows 2000 and Windows XP. The reality did not quite support that claim - and XP was at least unti SP2 a \"land of worms\".\nMicrosoft claims to have fresh new TCP/IP stack in Vista, written from scratch. Unfortunately - according to SG - this time it seems to be so. The reason why \"unfortunately\" are implication of having new, untested \"virgin stack\" for security. SG offers nice historical perspectives on issues of Windows networking implementation - mentions famous problems like machine freeze on packet with spoofed source address being same as destination, SYNC flood attacks, the \"ping of death\" and how all these were found and eventually fixed. Now, with fresh new stack, at least one of these problems that was fixed long back in the times of Windows 95 re-appered again in Vista.\nThe episode also gives very interesting peek on history of network stack in Windows. As SG points out, Microsoft suddenly got in Windows 2000 very good, solid and mature networking implementation, a huge improvement in stability and performance against previous versions of Windows.\nTCPIP stack is very complex piece of software and traditionally the most solid, most performant and certainly most secure implementation were found in open source Unix variants like FreeBSD and OpenBSD. Network experts use special tools to \"fingerprint\" the implementation - by sending specially crafted packets are analyzing the response, they can tell apart one implementation from the other, without actually having access to the stack's source code. And strangely enough - according to SG - the greatly improved Win2000 stack showed amazing compatibility and similarity in responses, quirks and \"fingerprint\" to BSD implementation :-). Draw your own conclusion\nI am pretty sure that decision to start from scratch and rewrite was carefully considered at Microsoft. There certainly were very many reasons for this: new features added, support for IPv6, and so on. Starting new often makes sense. What is wrong with it is presentation and marketing message that \"it is much better because it is new\".\nAs this article in Joel On Software puts it\n\"All new source code! As if source code rusted.The idea that new code is better than old is patently absurd. Old code has been used. It has been tested. Lots of bugs have been found, and they've been fixed. There's nothing wrong with it. It doesn't acquire bugs just by sitting around on your hard drive. Au contraire, baby! Is software supposed to be like an old Dodge Dart, that rusts just sitting in the garage? Is software like a teddy bear that's kind of gross if it's not made out of all new material .. \"\nWe will probably never know what was the real reason for TCP/IP stack rewrite, neither will know how to interpret \"amazingly similar\" behaviour of Windows 2000 stack and BSD implementation. The recent events of complicated deals related to intellectual property between Novell and Microsoft, and rumors of possible legal battles on IP with other Linux vendors, do not make it any clearer either.\nWhat almost sure, that despite the claims, we can expect old new bugs appearing in Vista networking and it will take quite some time until security experts as SG can test Vista enough to be comfortable with degree of security it really offers. I am in no hurry to upgrade - running Vista in virtual machine sounds like best approach right now, at least until Service Pack 2 :-).\n","date":"November 30, 2006","externalUrl":null,"permalink":"/posts/2006-11-30-vista-security-and-starting-from-scratch/","section":"Posts","summary":"I have read somewhere that quotation is safe way how to say something potentially dangerous or controversial without being legally exposed :-). So today I am going to quote an authority in computer security - Steve Gibson on some very interesting Vista related security information.\nSteve is doing (together with Leo Laporte) excellent weekly podcast \"Security Now!\". It is so great that I have decided to download as many back episodes as I could find on their site and started to listen to them in the chronological order, back from June 2006. It was worth of every minute. I am now somewhere in August 2006 and Steve Gibson (== SG) covered interesting tricks what to do with you hosts file, very nicely explained the usefulness of netstat program and started multi-episode sequence on virtualization and virtaul machines. Thanks to many years of experience, Steve always gives a historical perspective on every topic he covers.\n","title":"Vista security and starting from scratch ...","type":"post"},{"content":"Linkification Sometimes you see a Web page whose creator was lazy and did not wrapped displayed URL into \u0026lt;A href=\"...\"\u0026gt;\u0026lt;/A\u0026gt; tags. In short, you see something like http://www.thinknostic.com/ instead of http://www.thinknostic.com/ (btw, if you have installed Linkify, you will see both as links). As result, you can see the link on the page, but you cannot really click on it. In order to follow the link, you must select the link text, copy and paste it into address bar and press Enter. With Linkify installed, you will always see all textual links as real links and can just click on URL as if the page would contain the proper \u0026lt;A\u0026gt; tags.\nLinkification shows it's presence by small icon with letter L in status bar - tooltip on this icon shows how many links were converted. Right click on icon will allow to set options, and specify for example which protocols should be recognized.\n","date":"November 29, 2006","externalUrl":null,"permalink":"/posts/2006-11-29-feotd-linkify/","section":"Posts","summary":"Linkification Sometimes you see a Web page whose creator was lazy and did not wrapped displayed URL into \u003cA href=\"...\"\u003e\u003c/A\u003e tags. In short, you see something like http://www.thinknostic.com/ instead of http://www.thinknostic.com/ (btw, if you have installed Linkify, you will see both as links). As result, you can see the link on the page, but you cannot really click on it. In order to follow the link, you must select the link text, copy and paste it into address bar and press Enter. With Linkify installed, you will always see all textual links as real links and can just click on URL as if the page would contain the proper \u003cA\u003e tags.\n","title":"FEOTD: Linkify","type":"post"},{"content":"This is for Gabo, Derek, Steve and others who talked to me about podcasts and about which podcasts are worth listening to.\nSince I bought Nano2, I spend lot's of time listening to podcasts. Pretty much all driving time, walking time and time in the gym is spend listening to wide selection of topics and to people producing them.\nHere is my current list plus some additional recommendations:\n1) TWIT and all around Leo Laporte. This is classic. Go to twit.tv and choose from over 10 various podcasts. I am listening to This Week in Tech (Leo with John C. Dvorak and Wil Harris are great), Windows Weekly with Paul Thurrot, and definitely Security Now with Paul Gibson. Paul has amazing talent to explain complicated things in very understandable way. When I listen to this podcast, there are only two options: I either learn something new I did not know before, or I found better way how to explain something I knew before to somebody who does not.\nFor Mac users, you want to try iLifeZone and videocast MacBreak. The This Week in media is not bad either, but I find commercial breaks in this podcast pretty annoying. To subscribe to any of them, click on iTunes tab on the website.\n2) NOVA Science now\nLess \"geekish\" than TWIT, but very interesting, targeting science in wider range. Highly recommend the Twin Prime Conjecture episode.\n3) BBC Podcasts\nI always liked BBC for two reasons: their balanced, mostly objective news presentation (meaning both balanced point of view as well as understanding that North America affairs do not equal 90% of newsworthy world news) and for really cool British accent. The web newscast offers you the first benefit, but to enjoy the second, you need podcast. From the website you can subscribe to variety of podcasts - or listen in browser.\nThese three sources give me much more content than I have available time. But if you look into more variety, here are few more tips: try 43 folders podcast, Steve Pavlina podcast for for personal development, or Zencast if you are curious about meditation and Zen buddhism. Or just open iTunes, click on iTunes store (requires account at iTunes store), click on Podcasts and select from hundreds of free podcasts available. Happy listening.\n","date":"November 28, 2006","externalUrl":null,"permalink":"/posts/2006-11-28-podcast-du-jour/","section":"Posts","summary":"This is for Gabo, Derek, Steve and others who talked to me about podcasts and about which podcasts are worth listening to.\nSince I bought Nano2, I spend lot's of time listening to podcasts. Pretty much all driving time, walking time and time in the gym is spend listening to wide selection of topics and to people producing them.\nHere is my current list plus some additional recommendations:\n1) TWIT and all around Leo Laporte. ","title":"Podcast du jour","type":"post"},{"content":"Today's extension is about session management. Great news about Firefox is it's ability to use tabs and have opened many webpages at the same time. This impacts people's browsing habits - rather than following one path of the links and diving deep inside the Website, you explore many paths concurrently, jumping from one to another, adding more and more tabs at the virtual crossroads. As in real life, when you travel, bad things can happen - what in this case means that your browser may crash, leaving you in the middle of nowhere with no trace of how you have got there and what you have already visited. If you were using the Session Saver extension, this would be prevented - after Firefox restart you would end up with exact collection of open tabs as before the accident.\nOften you may want to close and reopen the browser deliberately: as you surf, the memory consumption goes up and up, because browser caches the visited pages to allow faster back arrow operations. When your memory consumption start approaching the fiscal deficit of a small European country, you may consider shutting browser down and restarting to get rid of some cache. With session saver on, you can do that without loosing context.\nUsing session saver you can simply close the session and continue browsing next time at the very same position as you stop. You can even have multiple named sessions saved and transfer session (the saved session file) between machines, using is as very complicated mass-bookmarking tool.\nDo not get discouraged by the very low version number: 0.2. Despite it, it works very well, much better than many software packages with version number 7 and higher ....\n","date":"November 27, 2006","externalUrl":null,"permalink":"/posts/2006-11-27-feotd-session-saver/","section":"Posts","summary":"Today's extension is about session management. Great news about Firefox is it's ability to use tabs and have opened many webpages at the same time. This impacts people's browsing habits - rather than following one path of the links and diving deep inside the Website, you explore many paths concurrently, jumping from one to another, adding more and more tabs at the virtual crossroads. As in real life, when you travel, bad things can happen - what in this case means that your browser may crash, leaving you in the middle of nowhere with no trace of how you have got there and what you have already visited. If you were using the Session Saver extension, this would be prevented - after Firefox restart you would end up with exact collection of open tabs as before the accident.\n","title":"FEOTD: Session Saver","type":"post"},{"content":"Technically, it was Sunday so rather than working or reading some serious stuff, I have decided to take a long walk (to catch up with lot's of new podcasts downloaded yesterday) and to surf the net just for fun. Here is some of the interesting discoveries:\nThere was a rumor on the net that some Indian student in Kerala discovered a way how to store over 450 GB of data on a sheet of paper. They say\ninstead of using zeroes and ones for computing, he used geometric shapes such as circles, squares and triangles for computing which combine with various colors and preserve the data in images\nThis discovery offers fantastic possibilities and could mean that CD's, DVD's and external hard disks will be soon obsolete. The only problem is that it is completely fake. Let's ignore for a moment the above quote - which btw violates basic principles of digital information storage: using just two values 0 and 1. Everybody with some understanding of electronics can explain why using more than 2 values is bad idea and does not help ...\nThe information capacity of the sheet of paper depends on it's size and print density. Let's do a ballpark estimate what this capacity can be: a sheet of paper of the size 8.5 x 11 inch has area of 93.5 square inch or roughly 100 square inch. If the technology used to put information on the paper is printing, with normal paper and normal printers we can assume realistic resolution about 1200 dpi (dots per inch) or 1200 bits per inch, which translates to about 1.5 megabits per square inch - or about 150 megabits per whole sheet. Which is less than 20 megabytes - a number several orders of magnitude smaller than claimed 450 GB.\nAll this was without any consideration for control information, division to some manageable units, correction codes etc and assuming than we would be able to exactly read all that was printed - with some sort of exact scanner that does not miss a bit.\nIn order to achieve capacity of 450 GB on sheet of paper, we would have to store 4.5 GB on square inch, which translates to density about 67 MB per inch or over 500 millions dpi. Which is seriously above capacity of any printer or scanner :-). If we would assume that we can indeed store more than just zeros or one in one pixel of information on paper, with the reasonable resolution of of 1200 dpi it would mean that we really have somehow represent over 400'000 values in single dot...\nI really do not understand why the large newspaper do not either avoid publishing materials from area they have no clue about or at least do not put at least minimal review process in place. Many people came to the same conclusion as me - e.g. this blog - as well as one my favorite internet celebrities John C. Dvorak did not miss a chance to bust the scam.\nBut enough about the fakes. Let's look at more real content: this google video puts very interesting sci-fi idea - going back in time - into software development and describes the debugger implementation that does exactly this.\nI also visited few pages that have really nothing to do with computers or technology - and found out that the type of alcohol you drink does make a difference on the second day. That was not a good discovery, though because my favorite - red wine - ended up second worst. Ouch. If you ever wanted to create a human face from component, see this web page (flash required). And finally, visit despair.com if you feel you need a fresh doze of (de)motivation :-).\n","date":"November 26, 2006","externalUrl":null,"permalink":"/posts/2006-11-26-weekend-nuggets/","section":"Posts","summary":"Technically, it was Sunday so rather than working or reading some serious stuff, I have decided to take a long walk (to catch up with lot's of new podcasts downloaded yesterday) and to surf the net just for fun. Here is some of the interesting discoveries:\nThere was a rumor on the net that some Indian student in Kerala discovered a way how to store over 450 GB of data on a sheet of paper. They say\n","title":"Weekend nuggets","type":"post"},{"content":"Thanks to 6 hours difference, I usually read tomorrow edition of Slovak and Czech newspapers on the Net one day ahead. Most of them switches to new edition at midnight, which is 6PM our time. I am doing this for several years already. What is different between now and 2-3 years ago is what I read. While before it were mostly articles written by journalists and news industry professionals, now I read mostly blogs. On SME blog, there are few hundreds, maybe few thousands bloggers, and content they produce is usually much more interesting and readable that the content of official newspaper.\nInterestingly enough, it is not only newspapers. If I sum up my information sources from the Net, maybe 70% of it is \"user created content\" - sites like Wikipedia, social bookmarking sites and aggregators such as diggdot.us, programmer's blogs and programmers sites (SourceForge, CodeProject.com), podcasts - all of them share one common feature: the content is not created by professionals, which are paid to create content.\nHow far will this continue ? Does this trend present a threat to professional journalists ? How far can these sites grow ? Will they be able to keep the quality and focus ? Is this just a new fad that will disappear - or will it change the landscape of news industry same way as internet changed software distribution or music industry ? What will motivate people to buy paper version of newspaper when you can get much more than you can eventually consume for free online ? How many sites can survive on ad income only - without charging subscription fee for access ? Only time will tell ...\n","date":"November 25, 2006","externalUrl":null,"permalink":"/posts/2006-11-25-are-blogs-the-threat-for-professional-journalists/","section":"Posts","summary":"Thanks to 6 hours difference, I usually read tomorrow edition of Slovak and Czech newspapers on the Net one day ahead. Most of them switches to new edition at midnight, which is 6PM our time. I am doing this for several years already. What is different between now and 2-3 years ago is what I read. While before it were mostly articles written by journalists and news industry professionals, now I read mostly blogs. On SME blog, there are few hundreds, maybe few thousands bloggers, and content they produce is usually much more interesting and readable that the content of official newspaper.\n","title":"Are blogs the threat for professional journalists ?","type":"post"},{"content":"In previous FEOTD entries I have mentioned excellent tools that help you maintain the URL's of the pages you want to remember (del.icio.us) , and in case the URL is not enough, save the content of the Web page for offline access or archive. But what if the web page is not really what you are interested in, you just want download all files files attached to the page - and there is a *lot* of them.\nIf this is the problem, do not search any further, this plugin is exactly what you need. On activation it provides you with links from current page, allows selecting which types of files or even individual links to download and creates a download queue. You can specify download directory and template for renaming files(this is very handy when several linked files have same name - e.g. images linked from different URL's).\nThe downloader is good netizen - it inserts delays between to downloads to give the web server on the other side time to breathe and serve other requests.\nThe URL is http://www.downthemall.net/\nHappy downloading !\n","date":"November 24, 2006","externalUrl":null,"permalink":"/posts/2006-11-24-feotd-downthemall/","section":"Posts","summary":"In previous FEOTD entries I have mentioned excellent tools that help you maintain the URL's of the pages you want to remember (del.icio.us) , and in case the URL is not enough, save the content of the Web page for offline access or archive. But what if the web page is not really what you are interested in, you just want download all files files attached to the page - and there is a *lot* of them.\n","title":"FEOTD: DownThemAll","type":"post"},{"content":"I cannot help it, but it is awkward feeling when something that was part of your life, was so omnipresent is announced to be dead and disappear shortly. Exactly this is happening to video tapes and format VHS specifically. The news has been all around the net day or two ago: studio's stopped after 30 years production and distribution of the VHS media.\nIt does not seem to so many years ago when VHS was and new and struggling to survive against more technically advanced BetaMax (I still remember how great the BetaMax movies looked). Now the VHS is slowly disappearing and everything moves to digital format and DVD. One one side, it is better - higher quality, less compatibility issues (no more struggling with expensive VHS players that can play both NTSC and PAL tapes on NTSC TV (strangely enough, the other way is much easier and many players sold in Europe do play NTSC tapes OK, but require 220 Volt/ 50 Hz and PAL TV). Compared to this, the DVD \"zones\" create much smaller problem, especially since Linux folks gave us some very good tools :-). Even the DVD and medium seems to be approaching the beginning of the end of life - albeit it is very unclear who will win the BlueRay / HD-DVD war. Maybe nobody will prevail, consumers will wait until the live with live streaming and video on demand with PVR's will be practical alternative to physical distribution.\nSo - as suggested in one of the blogs mentioned above - let's pause the PVR's for a minute of silence for VHS. And while doing that, let's contemplate what are we going to do with all the tapes with many unforgettable moments ? Maybe it's highest time to start converting them to something digital, before the VHS players become expensive collector's items as vinyl record players did ... Going digital is the only option ( at least you do not loose all your content as I did when I switched from reel tapes to CC or from CC to CD few years later - when MP3 came, I just ripped all my CD's). But it still feels a little bit sad - same as few months ago, when Nikon announced that they end production of film cameras\n","date":"November 23, 2006","externalUrl":null,"permalink":"/posts/2006-11-23-rip-vhs/","section":"Posts","summary":"I cannot help it, but it is awkward feeling when something that was part of your life, was so omnipresent is announced to be dead and disappear shortly. Exactly this is happening to video tapes and format VHS specifically. The news has been all around the net day or two ago: studio's stopped after 30 years production and distribution of the VHS media.\nIt does not seem to so many years ago when VHS was and new and struggling to survive against more technically advanced BetaMax (I still remember how great the BetaMax movies looked). Now the VHS is slowly disappearing and everything moves to digital format and DVD. One one side, it is better - higher quality, less compatibility issues (no more struggling with expensive VHS players that can play both NTSC and PAL tapes on NTSC TV (strangely enough, the other way is much easier and many players sold in Europe do play NTSC tapes OK, but require 220 Volt/ 50 Hz and PAL TV). Compared to this, the DVD \"zones\" create much smaller problem, especially since Linux folks gave us some very good tools :-). Even the DVD and medium seems to be approaching the beginning of the end of life - albeit it is very unclear who will win the BlueRay / HD-DVD war. Maybe nobody will prevail, consumers will wait until the live with live streaming and video on demand with PVR's will be practical alternative to physical distribution.\n","title":"R.I.P. V.H.S.","type":"post"},{"content":"This was is out-of order extension (I mean there are several extensions that I use on daily basis and for that reason I planned to mention them before this one) - but it helped tremendously in my BI project, so here it goes.\nLive Headers does one thing only and does it well - shows you HTTP headers of a communication between your browser and any Web site. As long as the browser is Firefox - but why would you want to use anything else, right ?.\nIt sounds simple - but consider the alternatives. What I was doing in such situations before was to set up a logging proxy that would intercept the HTTP Request/Response, log the data (or display them) and copy the request (or response) to the target. Yes it worked, but it is soooo much more comfortable just to click in the menu - compared to unpacking Tomcat, remembering how is the proxy configured, and so on ....\nBig thanks to Daniel Savard and Nikolas Coukouma who wrote this usefull piece of code.\n","date":"November 22, 2006","externalUrl":null,"permalink":"/posts/2006-11-22-feotd-live-http-headers/","section":"Posts","summary":"This was is out-of order extension (I mean there are several extensions that I use on daily basis and for that reason I planned to mention them before this one) - but it helped tremendously in my BI project, so here it goes.\nLive Headers does one thing only and does it well - shows you HTTP headers of a communication between your browser and any Web site. As long as the browser is Firefox - but why would you want to use anything else, right ?.\n","title":"FEOTD: Live HTTP Headers","type":"post"},{"content":"Since the beginning of the biometric security project, we are using an excellent enterprise-level Wiki Confluence as knowledge repository and main team communication tool. I was not sure at the beginning, how will the Wiki approach work for all the people on the team, mostly because once before I already tried it and had not much success of introducing the idea. It was few years ago and the Wiki engine I used were nowhere in the same league as Confluence, but main problem at that time was probably the users' mindset. I am happy to report that this time it worked really really well. I am not sure whether it was because of the fantastic user friendly features and capabilities of Confluence, or because the general awareness shifted thanks to sites like Wikipedia and people got used to the idea of user created content ... The truth is that Wiki's are mainstream now - inside or outside of the enterprise space.\nAnd here yet another proof for that: Microsoft launched the MSDN Wiki that merges content provided from MSDN documentation with user added/edited content. I think it is an excellent idea - MSDN documentation certainly can be improved and enhanced in many places and letting people who actually use the product contribute to the documentation content, is the right way.\nThe MSDN Wiki engine is right now IMHO nowhere close to to Confluence level of user comfort. From what I have seen so far, Confluence is the Lexus of the Wiki world.\nHere is the question: can largest software company in the world deliver something at minimum comparably as good (or better) as creation of a small, opensource-based softwarehouse from Australia (which using, on top of all, Java and Tomcat as the platform) ?\nWe will see. Maybe. Let's hope.\n","date":"November 21, 2006","externalUrl":null,"permalink":"/posts/2006-11-21-wikis-are-everywhere/","section":"Posts","summary":"Since the beginning of the biometric security project, we are using an excellent enterprise-level Wiki Confluence as knowledge repository and main team communication tool. I was not sure at the beginning, how will the Wiki approach work for all the people on the team, mostly because once before I already tried it and had not much success of introducing the idea. It was few years ago and the Wiki engine I used were nowhere in the same league as Confluence, but main problem at that time was probably the users' mindset. I am happy to report that this time it worked really really well. I am not sure whether it was because of the fantastic user friendly features and capabilities of Confluence, or because the general awareness shifted thanks to sites like Wikipedia and people got used to the idea of user created content ... The truth is that Wiki's are mainstream now - inside or outside of the enterprise space.\n","title":"Wiki's are everywhere ...","type":"post"},{"content":"As mentioned before, thanks to del.icio.us bookmarking site and excellent Firefox plugin with the same name, I have almost perfect solution where to keep and how to organize my bookmarks. In theory, I will never loose anything interesting. Or will I ?\nThe good news and the bad news about bookmarks is that they are very dynamic. What you've stored in your favorites or del.icio.us may disappear without warning and never come back (actually, thank's to Google caching it is not so bad, but even Google cache will eventually expire). In situation like this, I always wish to have captured not only link but the whole copy of the page(s).\nThis is exactly situation where Scrapbook is the perfect tool. With Scrapbook extension, you can very easily capture content of current page or current selection on the page and add it to your collection of saved fragments - your digital scrapbook. The content is saved nicely, with most features such as images, CSS or dynamic content preserved (local links are overwritten and so on). You can even organize your clippings into folders, manage them (delete or combine content), import or export them to very good looking HTML.\nIt is very easy to maintain several scrapbooks (for example by area of content or by project), everyone with folders. Later on, you can combine them, move content between scrapbooks, merge two scrapbooks or split one into two.\nIn newest version, it is very easy capture subtree - page with sub-pages - with limiting the depth of links and selecting type of linked files to download. For example JPG or MP3 - or whatever you want - but do not get me wrong, I do *not* recommend or even suggest that you should download MP3's - this is what iTunes was invented for ;-).\nSome of the other bookmarking sites save snapshot of the Web page when you bookmark it, which can sound better than having your bookmarks in one place and your saved pages elsewhere. I still like scrapbook better, though, because I can work with saved content offline and working with content takes lots of time. Most of the content I save (unlike URL's) needs some processing and have it available offline is very handy when you have your Macbook and some time available but no internet (for example at skating rink) ...\nHere is one little trick I use to overcome problem with multiple scrapbooks on multiple computers and their consolidation: on each computer I use, I create special scrapbook with same name as computer name (use Tools-\u0026gt;Extensions, Scrapbook -\u0026gt; Preferences-\u0026gt;Advanced and enable multiple scrapbooks first). This will be your default scrapbook for that machine. When you later on synchronize all computers against shared network disk (using any tool you want, e.g. Offline Folders or rsync), no information will be overwritten and you will have available all information from any Firefox - as long as the network disk is visible - to consolidate the content. And btw, the content is platform agnostic - scrapbooks created on Mac can be processed with Firefox on Windows and vice versa.\n","date":"November 20, 2006","externalUrl":null,"permalink":"/posts/2006-11-20-feotd-scrapbook/","section":"Posts","summary":"As mentioned before, thanks to del.icio.us bookmarking site and excellent Firefox plugin with the same name, I have almost perfect solution where to keep and how to organize my bookmarks. In theory, I will never loose anything interesting. Or will I ?\nThe good news and the bad news about bookmarks is that they are very dynamic. What you've stored in your favorites or del.icio.us may disappear without warning and never come back (actually, thank's to Google caching it is not so bad, but even Google cache will eventually expire). In situation like this, I always wish to have captured not only link but the whole copy of the page(s).\n","title":"FEOTD: Scrapbook","type":"post"},{"content":"Not only apple the fruit, but also Apple the company. How does it work ?\nStep 1: Buy an iPod. Any model will do, I have got Nano 2Gen, 4 GB\nStep 2: Subscribe to some good podcasts\nStep 3: Listen to a podcasts while taking long walks - outdoors (preferred) or in a fittness studio.\nThat's it. It works great for me. During last four weeks I have digested lots of podcasts, inclusive TWIT (This Week In Tech) netcasts from August 2006 almost up to today. It is a great way how to stay informed and get more interesting news while spending less time in front of the computer. And on top of that, you can have fun along the way. Leo Laporte is great host and personalities like John C Dvorak add lot's of flavor to the discussion. Few items from latest edition:\nWindows Vista has gone RTM The 64-bit version of Windows Vista will be much more secure than the 32-bit version. Jim Allchin claims that Windows Vista is good enough for his 7-year old without an antivirus. President Bush has given a plug to Dell televisions. Microsoft's review agreement for the Zune is rather restrictive. Forbes says that the Zune stinks. Microsoft is going to give Universal a fee for every Zune sold. Office 2007 has gone RTM. A judge has approved a challenge to the RIAA's $750-per-song claim. Apple has ditched the \"Mac Guy\" from its ads. Apple has released Macbooks with the Intel Core 2 Duo. CNet News and CNet have gotten Web 2.0 redesigns. A 43-year old software developer is now suing NTP. Google has accidentally sent the \"Kama Sutra\" worm to 50,000 people on one of its mailing lists. Bit-Tech has an article defending multi-core processors. I was was really surprised how many interesting podcasts exists out there. Many more than I have time to listen - it is hard to find more than 7-8 hours a week for listening and walking ...\nGreat source of podcasts are podcast directories - such as http://www.podcast.net/, http://www.podcastdirectory.com/, http://www.apple.com/itunes/store/podcasts.html, http://podcasts.yahoo.com/ and many others.\nIn case the podcast are not enough, try audio books - I have listened (during spring and summer) to all books from Ender series by Orson Scott Card and it was fantastic experience. It takes lot's of walking, though if you want to listen unabridged versions (typically 8-20 CD's per book). Recently, Ottawa Public Library started to provide audiobooks as electronic - unfortunately, the DRM is incompatible with iPod's so I will either have to get some cheapo MP3 player just for these books or stay with borrowing and ripping CD's with iTunes...\nMay the TWIT be with you ... and happy walking.\n","date":"November 19, 2006","externalUrl":null,"permalink":"/posts/2006-11-19-apple-makes-me-healthier/","section":"Posts","summary":"Not only apple the fruit, but also Apple the company. How does it work ?\nStep 1: Buy an iPod. Any model will do, I have got Nano 2Gen, 4 GB\nStep 2: Subscribe to some good podcasts\nStep 3: Listen to a podcasts while taking long walks - outdoors (preferred) or in a fittness studio.\nThat's it. It works great for me. During last four weeks I have digested lots of podcasts, inclusive TWIT (This Week In Tech) netcasts from August 2006 almost up to today. It is a great way how to stay informed and get more interesting news while spending less time in front of the computer. And on top of that, you can have fun along the way. Leo Laporte is great host and personalities like John C Dvorak add lot's of flavor to the discussion. Few items from latest edition:\n","title":"Apple makes me healthier :-)","type":"post"},{"content":"Got a new gadget. Actually, not quite \"got\" - just borrowed from Mike. It the digital pen - amazing piece of machinery, that remembers all you write (up to 40 pages) and allows you to transfer written text to computer. The catch is that you *must* write on special paper, with microscopic marks that help to note the position of the pen.\nI was surprise how successful was the CRC software of making some sense from my cat scratches :-).\nWhat I think is the best use of this tool for me: design. In the early phases when you draw boxes and classes and lines, you do not really need a design tool - something like Enterprise Architect or Visio more stands in your way than helps. Later on in the design process, you need a tool like these, but for the early phase - pen and paper is exactly what you need. We have been using whiteboards for this purpose and photographing them - but to get clean nice picture is great.\nSo - let's the writing begin - albeit it is weird to write without touching a keyboar :-)\n","date":"November 18, 2006","externalUrl":null,"permalink":"/posts/2006-11-18-new-toy/","section":"Posts","summary":"Got a new gadget. Actually, not quite \"got\" - just borrowed from Mike. It the digital pen - amazing piece of machinery, that remembers all you write (up to 40 pages) and allows you to transfer written text to computer. The catch is that you *must* write on special paper, with microscopic marks that help to note the position of the pen.\nI was surprise how successful was the CRC software of making some sense from my cat scratches :-).\n","title":"New toy","type":"post"},{"content":"","date":"November 17, 2006","externalUrl":null,"permalink":"/tags/browsers/","section":"Tags","summary":"","title":"Browsers","type":"tags"},{"content":"If you do not know and use on-line social bookmarking site Del.icio.us, take a break now and go there. Currently owned by Yahoo, is Del.icio.us is a one of many social bookmarking tools out. Probably not the one with most features, not the one with coolest user interface - but pretty good one and certainly winner for me.\nI have been struggling with the problem of how to keep my collections of URL's under control for several years. Yes - every browser has bookmarks or favorites, but if you use multiple computers daily basis (multiple means \u0026gt; 5), with actively accessing Web with more than single browser on each of them (usually with some subset of IE/Firefox/Mozilla/Safari/Opera), you can pretty much forget about browser's bookmarks/favorites - you will never have your bookmarks where you need them.\nI tried several programs that \"plug inside\" the different browsers and provide bookmark repository for all of them. Some of them were pretty sophisticated and allowed even synchronization of the url-bases between different computer - but ... It still had two problems: remembering to do manual synchronization was lot of work, error prone and generally PITA and as these computers were running different operating systems (Windows, Linux, Mac) I never found good software that would run of all platforms.\nThe solution was obvious: keep bookmarks on line, in some sort of online repository. With this, you will have your bookmarks available everywhere, as long as you have internet connection. Which is the only situation where you actually need a bookmark. I know, it takes some adjustments to entrust your precious But let's be honest - there is not much use for your bookmark when you are offline - what would you do with them.\nThe big pain with using on-line repositories is that you must use browser in order to enter them. The user comfort (or the lack of it) was largest problem for me to adopt the on-line bookmarking. Two things that changed it was AJAX and dynamic sites in style of Web 2.0 and tools integrating the repositories with the browser. These tools come in two sorts: for modern extensible browsers (such as Firefox, Mozilla or IE7) there are plugins, for the rest, there are bookmarklets - a tini Javascript programs that are accessible as bookmarks, but instead of opening new Web page, they can do something useful.\nThanks to Firefox pluging del.icio.us and bookmarklet for the same service in IE and Safari, I have finally all my bookmarks under one roof and accessible from any place. All 1225 of them - as of today. Why did I select del.icio.us and not e.g. Spurl, Furl, Magnolia, Clipmarks, Yahoo My Web ? I tried to use all the mentioned before, but del.icio.us had simples UI allowing fastest entry and it was backed by real company with revenue ( I was careful not to store my files on servers of a startup that can be out of business on a week notice). YMMV though - before making your own decision, see the Wikipedia page on social software, or the Social bookmarking faceoff article.\nIn the process of using it I have discovered the amazing aspect of the world \"social\" in social bookmarking. Unless you mark the URL as private, it is visible to everybody as well as it's classification (which is topic for another time). Clicking on the keyword/tag shows you all public links *anybody* classified same way. You can also select combination of keywords ... it is goldmine of information, co-created with over 500'000 of the del.icio.us users.\nWhat is so great about del.icio.us is the easy way with which you can add new bookmark and tag it with keywords. The easy and user comfort is in my opinion most important feature of the online bookmark manager. I have stayed with del.icio.us exactly for this reason: it requires minimum amount of work to enter and classify the url. It makes bookmarking AND tagging URL so easy that you'll never more will have a reason not to bookmark a site ...\nSee for yourself, create an account on del.icio.us, get the Firefox extension and enjoy !\nPS: You may also be intersted in this article on social bookmarking tools.\n","date":"November 17, 2006","externalUrl":null,"permalink":"/posts/2006-11-17-feotd-firefox-extension-of-the-day-delicious/","section":"Posts","summary":"If you do not know and use on-line social bookmarking site Del.icio.us, take a break now and go there. Currently owned by Yahoo, is Del.icio.us is a one of many social bookmarking tools out. Probably not the one with most features, not the one with coolest user interface - but pretty good one and certainly winner for me.\nI have been struggling with the problem of how to keep my collections of URL's under control for several years. Yes - every browser has bookmarks or favorites, but if you use multiple computers daily basis (multiple means \u003e 5), with actively accessing Web with more than single browser on each of them (usually with some subset of IE/Firefox/Mozilla/Safari/Opera), you can pretty much forget about browser's bookmarks/favorites - you will never have your bookmarks where you need them.\n","title":"FEOTD (Firefox Extension of the Day): del.icio.us","type":"post"},{"content":"It's been awfully quiet here in last two weeks. Mostly because it was awfully busy pretty much everywhere else. Being a single parent, even for a short and definite period of time is pretty demanding task. Now when my wife is back from the trip overseas, I do not spend my mornings and evening in various skating rinks, I am slowly catching up on everything that got backlogged, delayd and so on. Starting with my project and progressing slowly through my reading list, lot's of downloaded podcasts and LBNL (last but not least) the blog.\nTo speed up the catching up process, I am going to use excellent method from Steve Pavlina - the 30 day challenge. If you do not know http://www.stevepavlina.com/, put aside an hour or two from your browsing time and check the content - it is worth it.\nThe 30 day method in a nutshell, is:\n\" ... concept I borrowed from the shareware industry, where you can download a trial version of a piece of software and try it out risk-free for 30 days before you’re required to buy the full version.\"\nHow this applies to personal development is a psychological trick that removes the barrier of overwhelming challenge. Rather than committing yourself to something really hard - like going to the gym every day, you take on the \"shareware trial\" and agree that you will try to exercise just for 30 days and after that time you can stop, and still claim full success. There are two possible outcomes: either you discover that you really hate exercise and will indeed stop - and still feel great because you have achieved your goal. Or you will find out that being active makes you actually feel much better, that time spent in gym is no big deal and will move on exercising ... read more on Steve's blog. I can confirm that this approach works for me - I tried it this summer and really liked doing it (and no, it was NOT about exercise ;-)).\nBut back to the challenge: I am going to try post a blog entry daily for next 30 days, starting from November 17th until (pretty much) Christmas. I think I have enough ideas :-) for the trial - and will start with the Firefox extensions. Rather than doing a yet-another-list of Firefox extensions, I am going to concentrate on personal experience from working with that extension: what I believe is great about it, what is missing and make some suggestions for improvements or new features. Any bets how it will end ?\n","date":"November 16, 2006","externalUrl":null,"permalink":"/posts/2006-11-16-the-30-day-challenge/","section":"Posts","summary":"It's been awfully quiet here in last two weeks. Mostly because it was awfully busy pretty much everywhere else. Being a single parent, even for a short and definite period of time is pretty demanding task. Now when my wife is back from the trip overseas, I do not spend my mornings and evening in various skating rinks, I am slowly catching up on everything that got backlogged, delayd and so on. Starting with my project and progressing slowly through my reading list, lot's of downloaded podcasts and LBNL (last but not least) the blog.\n","title":"The 30 day challenge","type":"post"},{"content":"It's official. The Browser version 2 final is out. I mean Firefox, of course - it should be quite obvious what is \"the browser\" these days. Yes, I know - IE still holds majority of the browser share and yes, Safari is really really nice, fast and good looking application - but let's face it: browser is not just another application - it is a *platform* these days. Platform means extensibility and extensibility means being a good foundation for add-ons, extensions and plugins. And from the platform perspective, the Firefox is the king.\nThe negative side of being a platform is that you *really* need to think twice before you upgrade. It is not only the browser itself - the real value of Firefox is in its extensibility and in huge selection of available plugins. These plugins tends to check the browser version on initialization and chances are, some of them will stop working after the upgrade. Exactly this happened to me after I upgraded from one-something to one-five of Firefox while ago. It took about 3-4 months before I had all my \"plugins-I-cannot-live-without\" back working again. For the list - see the next blog entry.\nEven without the \"will my plugins work\" issue, upgrade is a big deal. The more we do rely on the Web 2 apps, the bigger impact can a broken (or changed) feature in browser have. It is not any more \"you cannot visit some WWW page\" issue - more like \"you cannot run this application\" problem. I do not know about you, but I would certainly miss Google Docs (former Writely and Google Spreadsheet), Remember The Milk, Delicious, Gmail and few others.\nInternet Explorer got major new release as well. After long long wait, the IE 6 was replaced by IE 7. It brings new amazing and newer-heard of innovations such as - tab browsing ! But seriously - it is good that IE got an upgrade and that the gap between Firefox and IE go smaller. Some features are very promising - like the RSS - and now IE is much easier extensible with add-ons. The selection of add-ons is no match to Firefox Extensions, but at least it is possible now.\nYou should be careful before you get you new blue e - not because many plugins would stop working - but because the switching back from IE7 to IE6 can be very hard - some people say it is close to impossible.\nTo keep on the safe side - try the installation in the virtual machine first. There are many these days: Virtual Server, VMWare. My personal favorite is Parallels - not (only) because it works on all OS-es I really care about - Windows, Mac and Linux and it just feels right. It is neither free (as beer) like Virtual Server 2005 or some products from VMWare nor free (as speech) like Xen - but it has one very important Mac-ish feature: it just works :-)\n","date":"October 28, 2006","externalUrl":null,"permalink":"/posts/2006-10-28-to-upgrade-or-not-to-upgrade/","section":"Posts","summary":"It's official. The Browser version 2 final is out. I mean Firefox, of course - it should be quite obvious what is \"the browser\" these days. Yes, I know - IE still holds majority of the browser share and yes, Safari is really really nice, fast and good looking application - but let's face it: browser is not just another application - it is a *platform* these days. Platform means extensibility and extensibility means being a good foundation for add-ons, extensions and plugins. And from the platform perspective, the Firefox is the king.\n","title":"To upgrade or not to upgrade ?","type":"post"},{"content":"I have been back since Monday October 2nd late night, but until today, the backlog of things in both projects did not leave enough time to do any blogging. Not even any project-unrelated thinking - which is a prerequisite. Thanks to long weekend, I almost caught up with my backlog in both projects, so I can get back to the fun part of business such as Internet and blogs ...\nTo answer the question how was the trip: Great!. Bratislava is really nice tourist destination (obviously, lots of British and Italian tourists must have found out too ...). Especially if your main area of interest is meeting people in pleasant environment of pubs, restaurants and caffee's, which are available in huge quantities in the historical downtown. This certainly was my main activity as I tried to meet many people from my \"previous life\". I did meet most of the people I wanted to meet (as well as few I did not expect to ;-)). Weather was fabulous, food was good (maybe even too rich), beer was (as expected) excellent and really affordable ( \u0026lt; $2 a piece).\nThe only real problem is smoking. It is mostly allowed everywhere - pubs, restaurants, caffee's, airports - you name it. In many places the idea of \"non-smoker's area\" is virtual line drawn in the middle of the restaurant, with no air flow limitation whatsoever ... It is not specific to Slovakia - Austria and Germany are pretty much the same.\nSecret hint: if you go to Bratislava, take your notebook with you. In the heart of the pedestrian zone, right in front of the City Hall there is a free WiFi, courtesy of the city council. Too bad I noticed it only 5 days before leaving. Enjoy !\nWhile I was travelling, few interesting things happened. The biggest (in both market impact as well as dollars transferred) was YouTube's purchase by Google. I guess many lawyers in USA must be very happy and very busy now ... as it is much more fun to sue somebody that actually does have money for copyright infringement, rather than cash-strapped startup. I dare to predict looots of such lawsuits. The lawyers will not have it easy - they may be challenging something really big. Not only financially. According to the Church of Google, Google is actually a real deity. And they claim to have a proof for it:\nGoogle is all-knowing (Omniscient). Google is everywhere at once (Omnipresent). Google answers prayers. Google is immortal. Google is infinite. (a mathematician in me has serious issues with this statement ;-)) Google remembers all (now this is scary !!) Google can \"do no evil\" (Omnibenevolent). See the Full proof and their very own 10 commandments .\nI can imagine this idea will create lots of emotional reactions. Depending on your personal standpoint in matters of religion and spirituality, you may find it all somewhere on the scale from \"terrible inexcusable blasphemy - how dare you ...\" up to \"excellent hilarious funny idea\".\nMake your own choice. But regardless where you stand, consider this (now I am *not* promoting or advocating here anything, so no flame wars plz):\nThe Church of Google believes we should be tolerant of everyone's beliefs, provided said beliefs hurt no one ...\nand\nGooglism has not started any religious wars, forced its opinions onto others, discouraged critical thought, objected to harmless lifestyle choices and most importantly, we have never attempted to scare people into believing they will suffer if they reject our religion.\nCan you say the same for your religion?\nIf you reject Google as your God, nothing negative (aside from your search results being crappy) will happen to you.\nEnough of this - quick look at other noteworthy nuggets from the Web:\nRoughly Drafted is very interesting read, especially if you have been around for a while, or if you care about history of computing. See the Rise and Fall of Platforms series. Recommended. Ian Landsman's thoughts on business of programming are also worth reading . Thanks to these guys I found out that I am 50% average person (whatever that means). Here is why: they published \"20 Things the average person doesn't know about XP\". After reading them, I found out I did not know about 10 of them. Now I only wonder is 50% of average better than average or worse ?? \u0026lt;grin/\u0026gt;... Web developers and Firefox users, note the 20 useful Firefox extensions for developers. Are there any web developers out the who would NOT use Firefox ? Just wondering ... If you use SQL Server, look at the T-SQL code snippets of this Narayana Vyas Kondreddi Ever wondered whether Yahoo Maps are better or worse than Google Maps ? See side-by-side comparison Another comparison - of anti-virus products can be found here To finish in a good mood - here is how to shoot yourself in the foot in various programming languages\n","date":"October 13, 2006","externalUrl":null,"permalink":"/posts/2006-10-13-back-again/","section":"Posts","summary":"I have been back since Monday October 2nd late night, but until today, the backlog of things in both projects did not leave enough time to do any blogging. Not even any project-unrelated thinking - which is a prerequisite. Thanks to long weekend, I almost caught up with my backlog in both projects, so I can get back to the fun part of business such as Internet and blogs ...\n","title":"Back again","type":"post"},{"content":"In few hours I am taking off for a quick trip overseas, which very likely means that I will be quiet - at least as far as blogging goes. Not that the place I am heading to is not wired enough - actually, the broadband penetration is surprisingly high. The real reason is that I will be moving around a lot and meeting lot of people, so the blog must wait (yes, I am taking the Mac with me - what have you expected ...).\nOn the topic of flying: this is hilarious account of what would a fly attendant say if they would drink Veritaserum before the safety instruction speech :-). Quick quote:\n\"Your life-jacket can be found under your seat, but please do not remove it now. In fact, do not bother to look for it at all. In the event of a landing on water, an unprecedented miracle will have occurred, because in the history of aviation the number of wide-bodied aircraft that have made successful landings on water is zero. This aircraft is equipped with inflatable slides that detach to form life rafts, not that it makes any difference. Please remove high-heeled shoes before using the slides. We might as well add that space helmets and anti-gravity belts should also be removed, since even to mention the use of the slides as rafts is to enter the realm of science fiction.\"\nYou can enjoy the rest here\nSee you in two weeks, assumed that Lufthansa makes it to Munich and Bratislava in one piece. If not - Yan knows all the admin passwords for the servers as well :-).\n","date":"September 19, 2006","externalUrl":null,"permalink":"/posts/2006-09-19-taking-off/","section":"Posts","summary":"In few hours I am taking off for a quick trip overseas, which very likely means that I will be quiet - at least as far as blogging goes. Not that the place I am heading to is not wired enough - actually, the broadband penetration is surprisingly high. The real reason is that I will be moving around a lot and meeting lot of people, so the blog must wait (yes, I am taking the Mac with me - what have you expected ...).\n","title":"Taking off","type":"post"},{"content":"I have been pretty quiet in last few days. The reason why was hinted here - we have finally a space. The project started on Monday and we were running around like crazy since Sunday. Started with moving in looots of boxes - 9 workstations, each with two 19\" LCD monitors plus three servers, network gears, cables etc - three full cars. Then came the unpacking and setting up, which took much longer time that I would ever have expected. But it went well - modulo few glitches - like missing DVI cables and only one disk in server that should have been RAID-ed ...\nThe new workstations are *really* nice, dual core AMD's with 2 GB RAM, dual DVI card with double monitors - fast like hell and very very quiet. RB Computing did an excellent job once again - thanks Rob, we'll be back. I think that the people on the team like it too - as Vlad put it, \"this is the first time in 6 years that I have better computer at work than at home\".\nThe location itself is pretty interesting. Building at 349 Terry Fox is full of startups, in various stages of development, financing or bankrupcy. All the time somebody is moving, walls are being built and torn down and you can find people at work after 1 AM. The place has it's own atmosphere and spirit, maybe closer to university than to a corporate building ... What is very good is parking - no more cruising around as at 555 Legget and waiting until sombody leaves. And of course view of a golf course. What is also perfect is that Tirestamp office is across the street - at 350 Terry Fox. It makes my life so much easier as I am involved in both projects ...\nWhile I was busy with getting things up, few nice things happens out there - like new IPods, especially the new Nano's - I'll wait if the issue with scratching are solved with the new surface and then get one for audiobooks. Also the iTV is very tempting with the price tag \u0026lt; $300, albeit the user interface looks a hell lot like Window Media Center. Is the similarity just an accident or (as Scobleizer thinks) did Apple for a change copied Microsoft ? Honestly - I do not really care. The iTV is a device that looks pretty good, offers very interesting features and if it is really quiet, I will buy one. The only confusing part is the name - why did Apple chose a name that is already taken ?\n","date":"September 14, 2006","externalUrl":null,"permalink":"/posts/2006-09-14-moved-in/","section":"Posts","summary":"I have been pretty quiet in last few days. The reason why was hinted here - we have finally a space. The project started on Monday and we were running around like crazy since Sunday. Started with moving in looots of boxes - 9 workstations, each with two 19\" LCD monitors plus three servers, network gears, cables etc - three full cars. Then came the unpacking and setting up, which took much longer time that I would ever have expected. But it went well - modulo few glitches - like missing DVI cables and only one disk in server that should have been RAID-ed ...\n","title":"Moved in ...","type":"post"},{"content":"Testing by itself does not improve software quality. Test results are an indicator of quality, but in and of themselves, they don't improve it. Trying to improve software quality by increasing the amount of testing is like trying to lose weight by weighing yourself more often.\nWhat you eat before you step onto the scale determines how much you will weigh, and the software development techniques you use determine how many errors testing will find. If you want to lose weight, don't buy a new scale; change your diet. If you want to improve your software, don't test more; develop better.\nSteve McConnell\n","date":"September 8, 2006","externalUrl":null,"permalink":"/posts/2006-09-08-quote-of-the-day/","section":"Posts","summary":"Testing by itself does not improve software quality. Test results are an indicator of quality, but in and of themselves, they don't improve it. Trying to improve software quality by increasing the amount of testing is like trying to lose weight by weighing yourself more often.\nWhat you eat before you step onto the scale determines how much you will weigh, and the software development techniques you use determine how many errors testing will find. If you want to lose weight, don't buy a new scale; change your diet. If you want to improve your software, don't test more; develop better.\n","title":"Quote of the day","type":"post"},{"content":"We will be moving into new office space soon. It is exciting time, stepping from working (mostly) at customer's locations to own project office. Location is of course Kanata Business Park North, with nice view to a golf course. This location brings several changes against the office in downtown - some of them are great - such as 1) we have lot's of space and 2) parking is not an issue - arrive any time, park as long as you wish. Some of them are not so great - selection of possible choices for lunch shrunk considerably (with very few in walking distance) and to get to closest Tim Hortons you have to drive (unless you are ready for 25 minute walk one way). In case you are wondering - we are keeping the office at Albert Street - it is managed by same company as the new place, so we are just scaling up.\nNow what relation has all this with the title - and who are the beduins ? Moving into own office may look these days like swimming against the stream. More and more people seems to be going the other way - out of office, towards working in public places - typically coffee shops (preferably with wireless access). It is quite a movement, judging by the topics of the blogs like Coffee Places Are My Office Space, Public Space As Office Space, The Coffee House Office of the Future or Why pay for rent and coffee?.\nSome consider this to be a sign of new wave of start-ups: The rise of the cafe start up, Coffee Shops are the New Garages, Forget garages coffee shops are where businesses get started or Web-based Apps plus Coffee Shop equals Start-up Company. The site Web Worker Daily is a virtual exchange board of tips and hints for the modern Bedouins - \"geographically uprooted from office-space, always-connected through wifi- and mobile broadband connections, laptop-hauling, latte-sipping cyber-beduins\". You can see them anywhere where they find WiFi connection or at least a power outlet. Our move from working mostly out at various customer's locations represents a sort of \"de-beduinization\" if you wish, settling down, putting down the roots :-)\nThis coffee-office culture is very visible in California (judging by the bedu-bloggers geography), but I've already notice signs of the new wave happening in Ottawa - even before I found the blogs above. Just look around in Starbucks at Chapters and you will find several people having meetings and at least 2-3 notebook workers every time. And btw - did you notice how many of these notebooks are actually Macs ?\nI like working in coffee shops and use them as \"creative retreat\" as often as possible. What is great is the smell of fresh coffee and proximity of large quantity of books. All together it creates very stimulating environment for creative thinking. But I am quite sceptical on idea of having Starbucks or other public place as primary working place - as many of the cyber-beduins attempt to accomplish. My two main objections are that you cannot really have quality business discusion or phone call in environment like that (because of noise and privacy issues) and complete lack of whiteboards in each of the mentioned coffee shops. As you know, one cannot do design of pretty much anything without proper square footage of whiteboard space - (sorry, all you UML design tools makers out there). Which is exactly why we are moving in rather than moving out.\nI am aware of the issues that such project office brings (or at least I think I am) - as Greg Olsen puts it:\n\"... dealing with real estate leases, leased-lines, routers, VPNs, servers, workstations, firewalls, DMZs, UPSs, telephone systems, voicemail systems, email systems, web servers \u0026amp; website management software, accounting software, sales \u0026amp; marketing software, software development software, groupware, IT support staff, attorneys, and many other things - none of which were directly related to our core business ...\"\nbut I can hardly wait until it happens. See you soon at the 349 Terry Fox ;-)\n","date":"September 7, 2006","externalUrl":null,"permalink":"/posts/2006-09-07-on-ottawa-beduins-or-we-want-starbucks-with-whiteboards/","section":"Posts","summary":"We will be moving into new office space soon. It is exciting time, stepping from working (mostly) at customer's locations to own project office. Location is of course Kanata Business Park North, with nice view to a golf course. This location brings several changes against the office in downtown - some of them are great - such as 1) we have lot's of space and 2) parking is not an issue - arrive any time, park as long as you wish. Some of them are not so great - selection of possible choices for lunch shrunk considerably (with very few in walking distance) and to get to closest Tim Hortons you have to drive (unless you are ready for 25 minute walk one way). In case you are wondering - we are keeping the office at Albert Street - it is managed by same company as the new place, so we are just scaling up.\n","title":"On Ottawa beduins - or - We want Starbucks with whiteboards","type":"post"},{"content":"Bruce Byfield has interesting article in Linux.com featuring hands-on comparison of four on-line wordprocessors: specifically ajaxWrite, ThinkFree Online, Writely, and Zoho Writer. I do not 100% agree with all his conclusions, but it's interesting and worth reading if you are exploring these tools. I am certainly staying with Writely, right now I am using it on daily basis. Combination of WriteRoom for off-line concepts and \"thinking phase\" of writing and Writely for on-line editing, adding links, etc fits ideally my needs.\nRegarding spreadsheets, Excellery seems to be addressing the shared pain of all on-line spreadsheet - which is need for connectivity. They claim that you can work on-line or off-line and synchronize. Sounds pretty good - I'll give it a try !\nThis article in Web Worker Daily talks about on-line spreadsheets as well as Forbes - which happens to nominate (my favorite) Google on-line spreadsheet to be the winner !\nGood choice, guys !\n","date":"September 6, 2006","externalUrl":null,"permalink":"/posts/2006-09-06-working-on-line-more-to-word-processors-and-spreadsheets/","section":"Posts","summary":"Bruce Byfield has interesting article in Linux.com featuring hands-on comparison of four on-line wordprocessors: specifically ajaxWrite, ThinkFree Online, Writely, and Zoho Writer. I do not 100% agree with all his conclusions, but it's interesting and worth reading if you are exploring these tools. I am certainly staying with Writely, right now I am using it on daily basis. Combination of WriteRoom for off-line concepts and \"thinking phase\" of writing and Writely for on-line editing, adding links, etc fits ideally my needs.\n","title":"Working On-Line: More to word processors and spreadsheets","type":"post"},{"content":"It is hard to imagine - on September 13th it will be 50 years since IBM introduced the very first hard drive.\nSince that time technology made quite a progress. Compare for yourself:\n1956 - RAMAC drive\ncapacity: 5 Megabytes, built from fifty 24\" spinning disks weight: about one ton price: $250'000 / year (lease) price per gigabyte: about fifty million dollars 2006 - typical harddrive\ncapacity: 500 GB weight: \u0026lt; 1kg price: ~ $300 price per gigabyte: about 60 cents Amazing, isn't it ?\nSee full article.\n","date":"September 5, 2006","externalUrl":null,"permalink":"/posts/2006-09-05-harddisks-turns-50-on-september-13th/","section":"Posts","summary":"It is hard to imagine - on September 13th it will be 50 years since IBM introduced the very first hard drive.\nSince that time technology made quite a progress. Compare for yourself:\n1956 - RAMAC drive\ncapacity: 5 Megabytes, built from fifty 24\" spinning disks weight: about one ton price: $250'000 / year (lease) price per gigabyte: about fifty million dollars 2006 - typical harddrive\ncapacity: 500 GB weight: \u003c 1kg price: ~ $300 price per gigabyte: about 60 cents Amazing, isn't it ?\n","title":"Harddisks turns 50 on September 13th","type":"post"},{"content":"Again, I need to make some space on a shelf and I simply cannot throw away a book ... This time I have decided to reduce my Java bookshelf to allow new (mostly .NET books) come in. No, I am not abandoning Java - but for next 8-12 months I am very likely fully booked in .NET projects, and after that, it will be time to upgrage to new sets of books for Java 1.6 anyway ...\nIf you are interested, send me an email. You can pick the books in one of our offices - either downtown or new one @ Terry Fox. Thinknostic people have first chance to select, but this offer is not limited to Thinknosticker's - so if you know me and have a friend who may be interested, feel free to fwd this email.\nSame as last time, I will donate unclaimed books to Ottawa public library. I plan to get rid of it before September 18th, so we have about two weeks.\nThe list of the books is here.\n","date":"September 3, 2006","externalUrl":null,"permalink":"/posts/2006-09-03-internal-free-books-to-a-good-home/","section":"Posts","summary":"Again, I need to make some space on a shelf and I simply cannot throw away a book ... This time I have decided to reduce my Java bookshelf to allow new (mostly .NET books) come in. No, I am not abandoning Java - but for next 8-12 months I am very likely fully booked in .NET projects, and after that, it will be time to upgrage to new sets of books for Java 1.6 anyway ...\n","title":"Internal: Free books to a good home :-)","type":"post"},{"content":"Continuing in Working On-Line Series - see previous post on word processors Spreadsheet is after editing text probably second most important business application. Let's explore what is out there for those of us, who do not want to install Microsoft Office or commit yourself to one particular platform. Most of the spreadsheet try to copy or emulate subset of the features of \"de-facto\" spreadsheet standard Microsoft Excel\nGood starting points for search is (obviously) Google search for \"on-line spreadsheet\" and Wikipedia. The offer of Web based spreadsheet programs is surprisingly large. They differ in capabilities, but typically allow import and export of Excel spreadsheets and CSV files, entering formulas (with subset of Excel functions), text formating, some form of graph creation and most importantly - colaboration and shared viewing/editing of the spreadsheet. I tried accomplish two task with some of them: import my timesheet from XLS and edit it online and do shared editing of a spreadsheet. Here is quick summary of the features and personal experience working with them.\nEditGrid offers very strong features, including:\nCollaboration with real-time update (RTU)- see changes immediately when someone modifies your spreadsheet. Full keyboard navigation. 500+ functions Automatic versioning Import and export in all common formats (MS Excel, CSV, HTML, Gnumeric, Lotus, OpenOffice, …). Permalinks for addressing your spreadsheets in different formats very easily. Comprehensive access control. Share to user, share with password, share to everyone, you control! Cross-browser. Fully supports IE 6.0+ and all Gecko-based Browsers (Mozilla, Firefox, …). Personal experience with EditGrid: nice, polished but fairly heavy. I have got few times \"script taking too long to finish\" warning from Firefox, something that did not happen with most others.\niRow is another very powerful spreadsheet with excellent 2D/3D graph capabilities. The look and feel is very Excel-like, including the color theme of the spreadsheets. Among other features, worth mentioning are:\nDynamic web functions: stockprice, convert Upload and save Excel,CSV and OpenOffice files Reference cells in other spreadsheets Draw bar/line/pie 2D/3D charts sample Allow multiple people to view or edit the same spreadsheet Automatically saves previous revisions Display a spreadsheet on any web page Generate HTML from spreadsheets Cell merge and un-merge Scroll-lock, hide rows or columns See also developer's blog and this review.\nWith iRow, unlike with others, I could not import my test spreadsheet - the formulas based on date calculation (date+1 as next date) which worked OK in Google, EditGrid and ZohoSheet - were marked as errors. There may be other way how to achieve same functionality, but this lack of compatibility with \"standard\" makes iRow less practical.\nZohoSheet (from makers of Zoho Virtual Office). Virtual Office is web based collaboration suite which contains applications like E-mail Client, Virtual storage for Documents, Personal and Group Calendar, Task Scheduler, Contacts Manager, Instant Messaging, Discussions board, etc. Zoho Virtual Office allows users to create multiple groups, and use all of these components within group. Independent applications ZohoWriter, ZohoSheet, ZohoShow (presenter), ZohoPlanner (task manager), ZohoChallenge (conducts on-line tests) and ZohoCreator (web page creation tool) are independent applications that complement the suite and make it full-fledge, platform and location independent office. Zoho makes also CRM which is of course not free application.\nIt looked very polished, I liked the long text overlap by default to next fields (same as excel) but I have received several time warning from Firefox that the script is taking too long - this never happened with the other's (except EditGrid).\nThere are many more, which I did not try out, for example Numbler or spreadsheet with yummy title NumSum - (is it just me or do you also feel like chinese buffet ?). Thinkfree office is more than just online spreadsheet: it contains bundles together tools that allow to create documents and presentations and 1 GB of free online storage. See the tour of the features.\nSecure Spreadsheet is targeting mostly business users. Its strenghts is multi-user environment and managing access rights of large user community. Unlike others, it is not free service and the plans start from ~ $10/usermonth.\nLast but not least - Google Spreadsheet\nAnother gift from Google is an on-line application, launched some time ago. This is the one that I actually actively use. It has maybe not as huge palette of functions or as polished interface, but it works very well. Concurrent editing works perfectly - we use it with Gabo to avoid emailing XLS documents.\nThe main dvantage of the Google spreadsheet is - well - Google. Despite the less features than other, relatively spartanian UI, missing Safari support (\u0026lt;sniff/\u0026gt;) - the Web powerhouse behind it makes long term availability of Google spreadsheet best bet from all the services above.\nThe google spreadsheet is not perfect. For example, it does weird formatting of the Weekday(Arg) results. I did not find how to show the Mon, Tue etc as in Excel. It shows instead numbers - 001, 002 to 006 and for some weird reason, 031 for Sunday. Despite of these problems, I will likely stick with Google Spreadsheet. It is very convenient to have single login to access Gmail, Google Calendar which I use a lot as well as spreadsheet. Also the concept of \"per-sheet\" sharing suits good my needs. It is very likely that the application will evolve and enhance .\nThis is enough for this part. If you want more details, either see this feature comparison or try for yourself.\nNote: This blog entry was written in Bridgehead Coffee on Richmod Road. Recommend. Nice place with comfortable seating, good coffee and organic cream / organic milk. And unlike Starbucks, Bridgehead really provides free wireless access. Nothing against Starbucks - I quite like the place and spend there a lot of time - but asking $7.50 for an hour of wireless access on top of $3.70 tazo chai is a shameless rip-off. Not mentioning that Bridghead looks like a company with strong ethical values and unlike Starbucks - they are Canadian company.\n","date":"September 2, 2006","externalUrl":null,"permalink":"/posts/2006-09-02-working-on-line-excell-ent-on-line-spreadsheets/","section":"Posts","summary":"Continuing in Working On-Line Series - see previous post on word processors Spreadsheet is after editing text probably second most important business application. Let's explore what is out there for those of us, who do not want to install Microsoft Office or commit yourself to one particular platform. Most of the spreadsheet try to copy or emulate subset of the features of \"de-facto\" spreadsheet standard Microsoft Excel\nGood starting points for search is (obviously) Google search for \"on-line spreadsheet\" and Wikipedia. The offer of Web based spreadsheet programs is surprisingly large. They differ in capabilities, but typically allow import and export of Excel spreadsheets and CSV files, entering formulas (with subset of Excel functions), text formating, some form of graph creation and most importantly - colaboration and shared viewing/editing of the spreadsheet. I tried accomplish two task with some of them: import my timesheet from XLS and edit it online and do shared editing of a spreadsheet. Here is quick summary of the features and personal experience working with them.\n","title":"Working On-Line: Excell-ent On-Line Spreadsheets","type":"post"},{"content":"See also Part I, Part II, Part III, Part IV and Part V\nThis Mac thing seems to be quite contagious. Gabo started to seriously considering buying the MacBook, after listening to my happy stories about Great Mac Discoveries. Even Vlad, right now living trough his latest love-affair with Ubuntu Linux was deeply impressed with OS-X after we seeing Expose, Spotlight, PhotoBooth and iPhoto in action.\nNext day, after I arrived to the office in the morning, Gabo was already there. Which is not unusual. Since his little son and wife are back, they get up quite early in the morning and Gabo usually beats me to arrive first to work. He lives only 5 minutes away anyway ...\nSo this morning he was there, sitting with sort of different look on his face and started with very unexpected question:\n\"What is different about me this morning\" ?\nI am checking - the mustache is in place ... no hair color change (at least not that I would notice ...). Trying to think about the clothing is hopeless - I never pay any attention to who wears what. Not even with women ... And why the heck does he ask such crazy question at all ? Is he OK ?\nBut he continues: \"How do I look today ?\" ?\nWhen I stare at him, and before I can say anything, he finally resolves the mystery:\n\"Do I look like somebody who ordered a MacBook\" ?\nNow that is a news. It took me well over 3 months to make the decision. It took Gabo about 2 weeks (and few days with my Macbook).\nAnd the best of all was Vlad's comment:\n\"You guys are dangerous ! I am now really in trouble - I want one too !\"\n","date":"August 28, 2006","externalUrl":null,"permalink":"/posts/2006-08-28-road-to-mac-vi-the-infection-is-spreading/","section":"Posts","summary":"See also Part I, Part II, Part III, Part IV and Part V\nThis Mac thing seems to be quite contagious. Gabo started to seriously considering buying the MacBook, after listening to my happy stories about Great Mac Discoveries. Even Vlad, right now living trough his latest love-affair with Ubuntu Linux was deeply impressed with OS-X after we seeing Expose, Spotlight, PhotoBooth and iPhoto in action.\nNext day, after I arrived to the office in the morning, Gabo was already there. Which is not unusual. Since his little son and wife are back, they get up quite early in the morning and Gabo usually beats me to arrive first to work. He lives only 5 minutes away anyway ...\n","title":"Road to Mac VI: The infection is spreading","type":"post"},{"content":"See also part I, part II and part III and Part IV\nAugust 13th # I have discovered wonderful thing today. I was experimenting with my PocketPC (Toshiba e830) and switched on Bluetooth. Mac discovered the device OK - all I had to do was to follow the wizard Setup Bluetooth device, under Bluetooth menulet (the strange B icon upper right). I have entered the code Mac suggested on PPC and they new about each other. What was really cool was that I found out how to access files on that device ... but let's step back a moment.\nThis was not my first attempt to use Bluetooth. On Thursday, when I had the Macbbok at work, and during lunchbreak, we have tried out to pair my RAZR phone with the Mac. It paired OK, but I was not able to see anything. What I was expecting was that the RAZR would somehow automagically show up in Finder or in Network - but it did not. Neither did the Toshiba, by the way.\nWhat I did today differently was that I tried Browse Device from the Bluetooth menu. And there it was - I saw the subtree of the PocketPC, everything under 'My Documents'. I managed to transfer files both ways like a charm.\nNow I realized - maybe I can do the same with RAZR. And indeed I could. Selecting Browse actually starts the application 'Bluetooth File Exchange'. The only trick with RAZR is to know where to look. It has 4 folders from the root:\n• MMC(Removable)\n• audio\n• picture\n• video\nbut the audio, picture and video are empty. You have to go into MMC, and there are another folders iTunes and mobile and the right place where to look for the images is in /MMC(Removable)/mobile/picture. I have created folder 'Photo from Phone' in documents, copied them there and imported with iPhoto. The added benefit is that the USB connection with my Fujitsu was always very very slow and unreliable - likely because of the RAZR issues. Using Bluetooth I can now copy images much faster, even if BT is not generally a speed devil ;-)\nCool, isn't it ?\nNow I have another motivation why to clean up the mess on my pocket PC 'My Documents' - it seems to be useful extension of my Mac for off-line data entry ...\nI got setting up other communication channels than Bluetooth as well. After configuring Mail and sending few test emails, I installed Thunderbird + downloaded emails from GMail. Using Adium we had first chat on MSN with Gabo. Audium is very nice and unlike MSN Messenger, you can access several IM networks at the same time, like MSN, Yahoo, AIM, Jabber - to name just a few. Unfortunately, the voice support for MSN is not available incurrent version.\nI also installed Skype . Works wonderfully, using just the build in microphone and speakers. Virtually no problems with echo. What is even better is to install Skype Beta with Video preview. That works perfectly with built-in inSight camera and you can have video conference with sound without any cables or peripherals sticking out, just with the Macbook, out of the box hardware.\nI have finished reading Switching to Mac on Safari. It was worthwhile investment of time and energy. After overcoming basic teething problems, I must say I feel very comfortable in Mac environment. I really like the keyboard and instantaneous connectivity after waking up from sleep. The network connection is considerably more stable than on PC notebooks. I work a lot in Starbucks during evening and weekends. The battery life is very good - I can get from 3.5 to 4.5 hours (with WiFi off, depending on CPU load and brightness of the screen).\nIt is about time to start work on blogging. I have tested few offline blog client: Journler, ecto and Qumana. Journler seem to be nice journal program, perfectly suited for keeping private journal and daily log, with some blogging capabilities. Ecto is on the other hand primarily blog editor. What I still lack is better understanding and experience with blog platforms. For the beginning, I want to go with free hosting on some of the popular sites. I plan to to start evaluation with Blogger , then test out Wordpress and eventually Livejournal .\nAfter I do this, I will post these \"back-blogs\", until now kept in pieces within various off-line tools: started with Journler, and continued with Writeroom and ecto. I really like Writeroom, but it does not let me insert links into text (unlike ecto). Interesting alternative to ecto is using Writely - new online editor owned by Google. It is now open for public registration and allows collaboration: you can ask extends access to any of your documents to selected people and collaborate. This seems to be the best option for processing the text initially drafted in Writeroom - for adding links, you need on-line connectivity anyway.\n","date":"August 26, 2006","externalUrl":null,"permalink":"/posts/2006-08-26-road-to-mac-v-feeling-happy/","section":"Posts","summary":"See also part I, part II and part III and Part IV\nAugust 13th # I have discovered wonderful thing today. I was experimenting with my PocketPC (Toshiba e830) and switched on Bluetooth. Mac discovered the device OK - all I had to do was to follow the wizard Setup Bluetooth device, under Bluetooth menulet (the strange B icon upper right). I have entered the code Mac suggested on PPC and they new about each other. What was really cool was that I found out how to access files on that device ... but let's step back a moment.\n","title":"Road to Mac V: Feeling happy","type":"post"},{"content":"See also part I, part II and part III\nAugust 10th # That Spotlight thing is just freaking fantastic :-). After few days of work, accumulating some files, emails etc, just for fun I typed Gabo’s last name to Command-Space search box. I did not even finish typing and first results were coming in the result list: all emails exchanged with Gabo, saved chats, text documents and as “best hit” Gabo’s contact card. Which was exactly right.\nSo what is so great on Spotlight ? What makes it any better than Google desktop or MS Search ? I cannot speak for MS Search, as I have not tested it, but I tried Google Desktop search on two different computers. What I liked on Google search was the extensibility - with custom plugins I was able to index almost every file format I was using. The only notable exception were old email archives in TheBat! format - anybody has a suggestion?. What I did not like was the price paid for all this. Not the $$, Google desktop is of course free. The price was very noticeable slowdown of the system. I even had to uninstall it from notebook, because it became unbearable slow.\nHere is my speculation why there is such difference in user experience: Google desktop is an add-on, not part of the OS and to find out which files were changed (and must be re-indexed) is has to crawl the filesystem to discover the changes. Spotlight on the other hand, is \"well connected\" and part of OS, it just sits idle, hooked to system notifications on file update system call and basically just handles events, never even looking on anything but changed files. With this aproach, the more files are on system, the bigger is Spotlight’s advantage. Difference in file system speed very likely also helps Spotlight. This is very subjective and I have never done any benchmarks, but whenever I was dealing with large directories (10000+ files) on Unix/Linux vs. on Windows systems (of comparable hardware parameters like RAM, CPU, disk size/speed), Linux systems always felt much faster and more responsive thank Windows. Yes, I know that 10000 files in single directory is crazy idea, but it changes nothing on the fact that Linux handled it better.\nSpotlight was forced to do some heavy lifting after I copied some PDF and CHM files from network to local disk. “Some” is a bit understatement as it was about 30 GB of content. After that, you could tell that something is going on. The slowdown was hardly in the same league as Google did to my other notebook, but it was observable - the CPU load as well as the disk activity in Activity monitor was considerably higher and the machine felt warmer. Processing the 30 GB took about 4 hours.\nUnlike Windows, Mac does not depend on Adobe Reader to open PDF file. PDF is handled natively, without any third party software, for both reading and writing. The Print dialog offers “Save as PDF” option for everything. I was little bit worried how will Preview handle the protected PDF’s I have purchased from APress. But they worked OK and looked so much better in Preview than in any reader on the PC. Why is it so ? Is it the fonts ? Or the screen ? Either way, avoiding Adobe Reader also on Mac is a great news. On Windows, I switched to Foxit Reader while ago(which does not need 25 second to just to start ;-)\nInstalling software on Mac turned out to be very simple and pleasant experience. Starting point is binary file with extension DMG (disk image). On doubleclick, Finder opens it, verifies content and mounts it as new disk - same way as you would mount a network drive or to see a newly inserted data DVD. After you open the disk, you see one or more icons. The whole install is drag and drop the to Applications folder and you are done. Uninstalling means dragging the icon to the trash. No installer formats to worry about (“is it MSI 1.0 or 2.0 ?”) or installing the installer before you install the application. What happens behind the scene is quite interesting. The single icon you are dragging/dropping, is in reality a folder, with application-specific structure underneath. You can even see it, by right-click (or ctrl-click) on the installed application and selecting “Show package content”. Application stores everything that is user specific under ~/Library directory, as ordinary files - so no registry is involved (and therefore nothing can get corrupted).\nI started my installation marathon with text editor: Smultron with yummy icon. It is much more programmer’s editor than the TextEdit . It helped me for several days as my main editor, until I discovered WriteRoom (see below). I tried and removed two TotalCommander replacements: - MadCommander free tool written in Java and Disk Order (30 day eval version). The first one just did not felt right. Disk Order was OK but I found excellent free equivalent - Xfolders. The more I get familiar with the Finder though, the less I think I will need it anyway.\nI also installed excellent CHM reader CHMox so I can read all my CHM books from Windows. Do not know why, but even MSDN in CHM format looks so much better and more readable on Mac … I also installed SeaShore (image editor, which I do not use much), and Firefox with some of my favorite plugins: (Scrapbook, Linky, Delicious, Web Developer, DownThemAll and SessionSaver). I found out that Safari as browser is quite nice and so far I am using both of them. It is convenient for simulating two different logins to same Web site from same machine.\nThe most interesting find was probably simplest as far as functionality goes. It is - writeroom - “clean” editor. What I like about Writeroom is the concept. It is a channel between the your brain and the computer file. Writeroom presents very minimalist typing environment. It has no rich text capabilities, you just select single, aesthetically pleasing font and that’s it. If you want, you switch it (with ESC) into full screen mode, where it hides everything and presents one large document area with no menu’s, controls, windows or anything that would ask for attention or dilute your concentration. It is just you and the keyboard. Strangely enough, it helps. It really makes easier to keep your thoughts focused on the topic, the tasks ahead and very successfully fights the urge to open this file, click on that or (just for one minute…), open just received email, answer that bouncing icon in the dock or try out out that new program from the Utilies I have no idea what it does ;-).\nWhere does Writeroom store the text I am typing ? It never asks for any file name or anything. It quietly creates and manages writerooms - some sort of persistent buffers, named by the first sentence in them and keeps them (likely) in the Library - user specific section of the application program. It is very convenient but it takes some time to mentally adjust to it. Not being able to see where your stuff is saved (and verify that it is actually saved) is very disconcerting situation for a WG (windows guy). In Windows, everything is file centric and you almost always know where your stuff goes. You have to, as for many years working with Windows 3.x and 9x, you have learned that the operating system may explode and die any moment, so your left hand does automatically that unconscientious “Ctrl-S” movement every few minutes or even more often. In fact, I am still doing the same - only it does not work. Instead of Ctrl-S the secret combination is now Command-S (alias Apple alias Pretzel key - S). Yep, I did it again ;-).\nToday, in the evening at Starbucks, I have experienced first “freeze” of the OS-X. I was copying some files from both USB drive as well as from my desktop at home, then I just closed the lid and left home. In Chapters, I noted that HERMES is still hanging in there and tried to “eject” it out. That was a mistake. It took about 2 minutes to recover (likely waiting some network operations to time out). The machine was not cold-frozen, but quite slow to react. I probably made it even worse when started panicking and clicking around, switching the network on and off, trying to call Expose and so on ….\nFortunately, it all came back nicely, without ugly measures (like reboot). Lesson learned: it is good idea to “eject” the network drive before going away - or at least, do not touch it while working offline.\n","date":"August 25, 2006","externalUrl":null,"permalink":"/posts/2006-08-25-14-road-to-mac-iv/","section":"Posts","summary":"See also part I, part II and part III\nAugust 10th # That Spotlight thing is just freaking fantastic :-). After few days of work, accumulating some files, emails etc, just for fun I typed Gabo’s last name to Command-Space search box. I did not even finish typing and first results were coming in the result list: all emails exchanged with Gabo, saved chats, text documents and as “best hit” Gabo’s contact card. Which was exactly right.\n","title":"Road to Mac IV: Getting accustomed","type":"post"},{"content":"See also part I and part II\nAugust 3rd # This is my second day with Mac, writing in TextEdit as I have not installed any other editor (yet). Still learning, do not want to install lot of junk before I find out proper ways how to do things. Time to learn how things are in the Brave New World ….\nFirst surprises and unexpected culture shocks: How do I get around ? Let’s have a look what is on the disk. So where are my disks ? Where is My Computer icon ? How do I see the content of the Disk C: (oops, I forgot - there is no disk C:, this is Unix !). Somebody please get me back my Total Commander … Even the braindead Windows Explorer (which I never use on Windows because TotalCommander is sooo much better) would help.\nAt the first look, the whole windowing and menu concept is weird. I am just not used to watch up (to the top of the screen) to see which application is running. It is especially confusing, when I have no windows open. Why does the application does not end when I close all windows ? It just hangs there and unless you note the menu up there, you will miss it.\nAlso the “dock” concept is quite alien. Dock is a strange cross of the start menu shortcuts and Windows dock. You see both the applications that are running and those who are not running, distinguished only by tiny (for eyes of a Windoze user quite unsignificant) black triangle. And to make things even worse, from the right side of the dock, there are some minimized windows. Complete chaos! You click on an application with the black rectangle (the running application) - and nothing happens. One would expect a window popping up or something .... Did the application hang or what ? You start to fear that the whole system freezes and the screen goes blue … and then you realize this should not happen (or at least it would not be the good old BSOtD ). After closer examining the very top of the screen you find out that something did happen - there is name of the application out there, but still no windows whatsoever. How can it be ?\nEven your buttons seems all wrong. You see familiar Control and Alt (dubbed as Option) but what is the pretzel key for ? And what exactly is Fn button for - is it just usual laptop thing (to make up for the missing numerical keypad etc) or is it fourth modification button ? To add frustration to the confusion, you quickly realize that the is Control not Control. Pretzel is the real Control button - because Save shortcut is Pretzel-S, not Control-S. Actually, not quite: sometimes the Option key is the control - try for example skipping in text line by word left and write: the Control-Left/Right (now I mean the Apple ctrl, not Windows Ctrl) takes you to the beginning and end of the screen. To move one word left or right, you have to use option-left/right. Oh gosh, this will be even even worse as when I was learning Emacs in 1998, I guess. On the other hand, Emacs will be really easy now \u0026lt;grin/\u0026gt;.\nIn addition of feeling lost, there are also some wonderful discoveries. I quickly learn to love F9 and F10. F9 quickly rearranges all open windows on the screen and allows to select one. F10 does same thing within windows belonging to one application. Now I know where the same feature in Vista comes from ;-). Alt-Tab still works, only it is not Alt-Tab but Pretzel-Tab. Plus we have Pretzel-~.\nI guess it’s time to start learn how to survive in this strange new world. I start Safari (the browser), go to Safari (the O’Reilly On Line books) and find the “Switching to Mac, Tiger edition”. Time to tame the Tiger…\nAfter some reading and mental adjustments, thing start to make sense. I learned that the correct name for pretzel key is Command - which reminds me to old Linux time when I was fluent in Emacs and had to translate the other way ;-). I even dare to open System preferences and start customizing few things.\nI tried the “magnifying” dock buttons but found it very disturbing, so I have switched them back off. I really like the “menulets”. Nicely done for the battery, network, bluetooth, time. From the book, I learned how to add the Eject menulet.\nI slowly work through the basics and start to be accustommed to different way how to do things. One huge jump in my productivity was when I decided that it is time stop fooling around with the trackball and get the mouse. There is nothing wrong with the Macbook’s trackpad - I managed to get the “click” emulation with knocking pretty quickly. It is actually probably one of the best trackpads I ever worked with - just try using two fingers for scrolling - it is insanely cool and practical. It is just that holding Ctrl whenever I need right click does not suit me and doing drag and drops without mouse sucks, regardless of the platform - period.\nI was contemplating of getting the original - Mighty Mouse - but could not decide whether to go for classical version or newly introduced and more expensive wireless version. I was not sure what is the battery life, how it behaves - nobody from Google search results had any meaningful practical review. People were generally positive about the classical Might Mouse, but from the few cases I tried it out in Compusmart or Bestbuy, I was just not convinced. It just did not fit right into my hands, formed by by long years of using Microsoft and Logitech mice. So I postponed the buying decision - and I am glad I did.\nIn Futureshop I saw the bluetooth version of the same wireless USB mouse I use for almost 2 years with my Fujitsu. It is small, has very good battery life (1-2 months) and feels just right. Few days later I have got confirmation of this mouse gut feeling from real Mac authority - Leo Laporte - in MacBreak (watch it here).\nSpent a lot of time playing with built-in camera. The Photo-booth is endless fun, my daughter loves it ! But let’s try to do some of the cool multimedia stuff the Mac Guy was saying they are so easy - let’s make a movie ! So let’s download some MPEG’s from my camera and burn them …\nWell, not so fast. First thing I learn is that my MPEG’s are not recognized by neither Quicktime, not iMovie - here is why. It costs me $20 USD to get the plugin that can read the MPEG2. Now the iMovie understands the clips - unfortunately, there is no sounds. To get sound, I need to do some conversion from MPEG2 produced by Sony. I am luckier this time, for I can use this opensource tool. Wide variety of opensource software for Mac is a nice surprise. I can find lots of interesting links on the Web - for example here and here. After playing with all that multimedia stuff for few hours, I almost get to the point of having some sequence of scenes that start to resemble a movie. Working with iMovie is very time consuming activity and as it is almost 3 AM, I decide to postpone my first movie until\nI get at least some understanding of all that jazz around video formats, codecs, MPEGx differences , I have chance to go through some basic iMovie tutorial (as I am barely just scratching a surface), I feel at least a little bit at home with basic Mac skills so that I do not have to fight with essential things and finally I will have some clearer idea about the content of the movie (like some sort of script) ","date":"August 24, 2006","externalUrl":null,"permalink":"/posts/2006-08-24-road-to-mac-iii-the-culture-shock/","section":"Posts","summary":"See also part I and part II\nAugust 3rd # This is my second day with Mac, writing in TextEdit as I have not installed any other editor (yet). Still learning, do not want to install lot of junk before I find out proper ways how to do things. Time to learn how things are in the Brave New World ….\n","title":"Road to Mac III: The Culture Shock","type":"post"},{"content":"See part I\nJuly 25th - August 2nd # After ordering, I received two emails from Apple, confirming the order. It took 3 days until the order finally got shipped from China (where else, of course) on Friday, July 28th and the estimate for delivery was 5-8 business days. I have received the tracking number and was able to track how my Macbook was moving around the globe: starting from Shizou, China on 28th, arriving to USA, Anchorage, Alaska one day later. One more day and it showed up in Memphis, Tennessee. That was on July 30th. It seemed to stuck there for over 2 days and then, without any interim stops it showed up on August 2nd in Ottawa Fedex location. I have just arrived to customer place in the morning and saw the news on Fedex Tracking page (dutifully bookmarked and checked every few hours )…\nIn two hours, it was delivered. So the “birthday” and timestamp for the beginning of my Mac experience is the August 2nd, at about 9:50 Eastern Standard time. Fortunately, at that day I had arrived to work at 7 AM so I was able to finish everything I had planned for the day and leave relatively early. At about 4:30 PM back at home I started to unpack the package. I did it really slowly, enjoying it a lot and throughly documenting ever step with my D70. This was first time that I have ordered anything else than books and tickets from the Web - so it was a kind of “leap of faith” to pay around $2000 to company who will ship the thing from different side of the globe. Maybe I was suspecting that something could be broken, or something will not be as I ordered - but fortunately (as I found out in next hour), no surprises there. It was nice to find that this global ecommerce thing everybody talks about actually works :-)\nBeing educated by various Windows products manuals “NEVER attach the disk before installing drivers” or “do NOT switch it on before doing X.Y.Z” I actually did not switch the notebook on before scanning the manual. Yep, you heard correctly: I actually did read the manual first \u0026lt;grin/\u0026gt;. I have to say that it was beautifully short, good looking and thoroughly understandable, without insulting reader’s intelligence. It was that type of manual, that even my mom (who never touched a computer) would probably understand how to start and what to do - if she spoke English, of course.\nTo charge the battery, I unpack and connect the power supply. This simple thing lies on the floor right next to my Fujitsu power supply and the difference could not be more revealing. The Fujitsu power supply is large, heavy, ugly brick, weighting about 4 times as much as as nice and small Apple white box. Not only that - note the small details: how the brick allows attach/detach either power cable or direct right-to-the-wall plug. The hidden collapsible “ears” that serve as holder for the thin computer power cable loops. And the nice small magnetic ending that can be plugged to the notebook either side up …\nWith all this done I dared to press the button and “bang” - off it went. The system booted (without Microsoft sound, but one would not really expect it). OS-X started, asked me few questions about country and language setting and myself and I was in.\nFirst experience in four words: Looks just plain beautiful.\nSecond experience in three words: It just works !\nEverything on the screen looked so nice, polished, with very smooth typography. I pressed by chance F12 and wow - I saw the Dashboard for the first time, with Weather widget configured to Ottawa and clock showing my local time … It must have got it from my address, I typed in when registering.\nNote: as I discovered two weeks later, when comparing weather forecast from Weather Network with the one from Dashboard widget, it was different Ottawa which got configured by default: Ottawa in Kansas, USA rather than Ottawa, Canada . Now this is really confusing: not only these cities have same name, they even have both university with almost identical name: see the real one (University of Ottawa) and the Ottawa University in Kansas. Obviously, the setup picked the first Ottawa it found and did not bother compare the country. I changed the city in the widget and got the temperature down to real values.\nI even dared to switch on the Airport (aka wireless card) right away. I was expecting to have to set the security protocol and experience same issues as few years ago when I started to use wireless router: during setup, you need to select from different settings none of which is really explained (like WEP, WPA, WPA-PSK). After you spend some time surfing the web and reading, you'll find out what these acronyms actualy represent. But if all you want is to get secure wireless connection quickly, you do not really care about the differences between these standards. Fortunately, Macbook figured it out without troubling the user with too many details. It saw my home network right away, just asked for network password and again - it just worked. What a relief. On the other hand, I do not know what I could do if it did not work, not having any parameters to set. Probably I would have to Google a lot, then go down to the depths of command line and Unix commands I never knew they exist …\nThe wireless also seems to be way more stable with Mac than with my Windows based notebooks (both Fujitsu and tablet). But to be fair - my experiences of instability are from last two years and I have replaced the router recently. Instead old WRT54G, Yan brought home some Dlink router with pre-N capabilities (which I do not need and do not use) and range boost (which I do need and enjoy !). The new router is more stable but I have already seen few “Could not connect to preferred wireless network” messages in the morning on both Windows macgines and weird connection delays (2-3 minutes) after waking from hibernation. The Macbooks just wakes up from sleep and in 10-20 seconds is online.\n","date":"August 23, 2006","externalUrl":null,"permalink":"/posts/2006-08-23-road-to-mac-ii-ive-got-a-macbook/","section":"Posts","summary":"See part I\nJuly 25th - August 2nd # After ordering, I received two emails from Apple, confirming the order. It took 3 days until the order finally got shipped from China (where else, of course) on Friday, July 28th and the estimate for delivery was 5-8 business days. I have received the tracking number and was able to track how my Macbook was moving around the globe: starting from Shizou, China on 28th, arriving to USA, Anchorage, Alaska one day later. One more day and it showed up in Memphis, Tennessee. That was on July 30th. It seemed to stuck there for over 2 days and then, without any interim stops it showed up on August 2nd in Ottawa Fedex location. I have just arrived to customer place in the morning and saw the news on Fedex Tracking page (dutifully bookmarked and checked every few hours )…\n","title":"Road to Mac II: I've got a Macbook !","type":"post"},{"content":"Just stumbled upon this blog and noted at least three things of interest:\nhe has got a new a Mac Pro (I am green with envy :-) ) uses as a nick nice wordplay on MacGyver (this name has special meaning for all us, ex-Montage folks) he started to learn Objective C and Cocoa and blogs about it, I am curious - (not that I plan to give up Java, C# and Python ..) Also see his list of recommended (mostly) free Mac applications. Going to try out some of them for sure !\n","date":"August 23, 2006","externalUrl":null,"permalink":"/posts/2006-08-23-list-of-mac-applications-by-macgiver/","section":"Posts","summary":"Just stumbled upon this blog and noted at least three things of interest:\nhe has got a new a Mac Pro (I am green with envy :-) ) uses as a nick nice wordplay on MacGyver (this name has special meaning for all us, ex-Montage folks) he started to learn Objective C and Cocoa and blogs about it, I am curious - (not that I plan to give up Java, C# and Python ..) Also see his list of recommended (mostly) free Mac applications. Going to try out some of them for sure !\n","title":"List of Mac applications by macgiver","type":"post"},{"content":" January - July 2006 # This is the story of a journey travelled quite often these days. It describes discoveries, joys and frustrations of one long time Windows user learning how to use Mac OS-X. Many have done this before, many have blogged about it.\nThe reason why I am writing this down is mostly to remember, and as well because I can. One of the assumes uses of the new MacBook was creative writing so I guess I am trying fulfill the promise to myself. I have no idea whether this will be an interesting read for anybody else but me. But I’ll write it anyway.\nThis sort of “back-blogging”. I am using my notes from PC and from the Web to reconstruct these events.\nWriting of this chapter was started exactly as I have imagined it before I decided to get a Mac. I am sitting in Starbucks (Kanata Chapters, for a change - my home Chapters at Pinecrest will have to have to wait few more hours for the premiere), in comfy-chair a typing into wonderfully simplistic editor Writeroom, in full screen mode, free of any disruptions.\nIn order to understand it all better, let me present my professional background and bias. I have started to work in the IT field almost 20 years ago in 1987, right after I’ve my Master’s degree in Computer Science. I spent most of my professional life in Windows or other Microsoft-made environments. First contact with Microsoft made operating systems started in 1988 with MS-DOS and continued through MS-DOS enhancements-slash-replacements (such as Windows 3.x, Windows 95). I was using mostly C and later C++, in various incarnations. From Borland’s fantastic Turbo C trough Zortech C++ to Turbo C++, Microsoft C from 5.1 up to 7.0 and then Visual C/C++ from 1.0 upwards. I have had the opportunity to code in Visual Basic, from 3.0 up to 5.0 as well as way too many VBA dialects (anybody remembers genealogy of Access Basic or first Excel with VBA style macros?). All this lasted up to 1998, when I seriously got involved with Java (at that time, the underlying OS was mostly Windows NT). It lasted until 2003 and it sort of loosened the Microsoft link, but most of the time, even in Java, I was using Windows as main development platform and Unix was usually only the deployment platform.\nDuring last 5 years, I made few attempts to feel really at home in Unix and Linux. To certain degree I have succeeded. What I never accomplished was getting to the state where Linux would become my primary or preferred platform. There were always things that were so much easier in Linux, but there was always lots of things that were awkward, hard to remember or just inconvenient outside of Windows. Even as Java programmer, I was still more productive in Windows: the new versions of JVM were available for Windows first and for quite some time, Linux was second class citizen in Java world - just recall the issue around native threading vs green threads. It got all resolved, but it took time.\nCorporate environment, office file formats and compatibility issues were always a big deal. Remember, that was early 2000’s and OpenOffice with its capabilities of reading and saving Word documents were still quite far away … Linux (and Unix) was always mostly production or server environment. I was able to do what I needed to do but never made the step to leave the Windows quite behind.\nSo here I am, locked with Windows for most of my professional career, getting ready to jump to the Mac platform. Couple of years older and (hopefully) a bit wiser than in 1999-2000 when I tried to switch to Linux, I did not plan to switch to Mac and go away from Windows. With majority of my projects coming from .NET space, it would make little sense and would be probably pretty bad for the cashflow. What I wanted to do was to embrace, include Mac into my digital world.\nOne of my friends did try to really switch to Mac in early days of OS-X (2000) and to use it as his main and only platform inside medium size organization. He bought the coolest looking notebook at that time (17” Powerbook) and tried to merge into corporate world of Windows domains and Microsoft Office documents. After few months, he gave up and went back to Windows. If he had done it today, very likely it could work - with advances in OS-X, Openoffice 2.0 available, he would be able to do most of his work on Mac. Thanks to Intel based Macs and software like Parallels and VMWare, he would likely got over to largest obstacles of Windows defectors: how to replace/work with others who use MS-Project and Visio.\nWhat was my motivation to get a Mac in a first place: curiosity. There was lots of buzz on the Net about Mac software and Mac culture. The people I knew who used Mac, were usually very happy and quite passionate about it. I am happy owner of both Nikon DSLR and Sony HDD camcorder and whenever I tried to google how to do this or that with pictures or video, I ended most of time in software for Mac platform. Even such non-artistic, non-visual area as personal productivity and implementation of Getting Things Done was dominated with Mac tools and Mac people: the best recommended system was kGTD (Kinkless GTD), implemented as collection of AppleScript on top of OmniOutliner Pro.\nI started to think about getting the first hand experience with Mac shortly after January Intel announcement and Apple’s introduction of Macbook Pro. I was already toying with an idea of getting another, small, very portable just-for-fun notebook that would be dedicated not to work, but to reading books, surfing web, writing and managing my digital life: pictures, music, video and so on. True - it would be the fourth notebook in the household (in addition to about 5 desktops) - after my 16” Fujitsu N5010C, Toshiba M200 tablet and old P3 based Toshiba - but I managed to convince myself, it would be useful: the Fujitsu is very heavy (7-8 kg) and not exactly portable, with battery life about 70 minutes, tablet is being used and does not have really nice screen (few of tablets have) and the P3 Toshiba barely runs Win98 or Linux. So new small and light notebook with good battery life would really help.\nAt first, I was looking either on very good looking Vaio subnotebooks (something like Sony’s VGNSZ260PC or similar small notebook from Fujitsu something like P7120 or newer Q2010. The problem was very high price - around $3000, much more than I was willing to pay for the fun. And then, 13\" Macbook was announced with starting price of $1500, with of the size I still could consider very portable and it created interesting dilemma: for about 50-70% of the price Sony/Fujitsu, I could get one beautifully made, cool looking small notebook, but not Windows one. I would not be able to do everything what I was doing on desktop and the other windows based notebooks. Or would I ?\nI started to compile list of “all I wanted to do with Mac” and search for appropriate software. I was spending lot of time on Mac related sites during April-May, going in circles between two extremes:\nAbsolutely yes. I have to try it out why are all these people so crazy about OS-X. It must be soooo much better than Windows. Are you crazy ? Spending almost 2K on a toy that you do not really need ? Besides, all you want to do can be done in Windows and you already know how to do it. If you now get something completely different you will be wasting time getting up to speed and resolving the issues you do not even know you exist … What was influencing me most were forums and issues people were experiencing with Macbooks. Three main scarepoints - things people were complaining about were\nMacbooks are loud and make very irritating “mooing” noise the discoloration problem - yellow stains appearing on white surface after 2-3 weeks of use Overheating problem The discussion seemed to be going forever… and I was still watching them and waiting for fixes … and doing nothing. What won at the end, was curiosity and comparison of pros/cons. If I would buy Macbook and if the Macbook and OS-X would not live up to my expectations, the 2K is probably acceptable tuition fee - and I would get as reward more enthusiasm for Vista and Microsoft in general. By not buying, I may miss great opportunity to learn and enjoy something that is new, elegant and fun - and how often does life give you such chances? What also helped was acknowledgment of discoloration issue as a production problem by Apple and few reasonable voices in forums (which I forgot to save but in a nutshell they were saying that):\nthe loud voices of unhappy owners may represent very little fraction of the users. It may be much smaller percentage than with other products. The happy users have usually less incentives to write about how great are things working Mac community has often much higher expectations and standards and what is being complained about may be not a big deal at all Apple’s supposedly has better quality record than most of PC based notebook manufacturers Decision day came late July. I logged on to Apple Webstore and ordered white MacBook, 2.0 GHz dual core CPU, 1 GB RAM and 100GB hard disk. I could have saved some money on going with smallest configuration in 2.0 GHz processor class and upgrading RAM/HDD myself - but I did not feel like touching the machine before I learn about it and certainly did not want to exchange the hard drive…\nThe order was submitted on 25th of July and the wait started ….\n","date":"August 22, 2006","externalUrl":null,"permalink":"/posts/2006-08-22-road-to-mac-i-hard-decisions/","section":"Posts","summary":"January - July 2006 # This is the story of a journey travelled quite often these days. It describes discoveries, joys and frustrations of one long time Windows user learning how to use Mac OS-X. Many have done this before, many have blogged about it.\nThe reason why I am writing this down is mostly to remember, and as well because I can. One of the assumes uses of the new MacBook was creative writing so I guess I am trying fulfill the promise to myself. I have no idea whether this will be an interesting read for anybody else but me. But I’ll write it anyway.\n","title":"Road to Mac I: Hard Decisions","type":"post"},{"content":"If you would ask me to pick one technology phenomenon that had the largest impact on and was the most characteristic for the technology during the years 1995-2000, my answer would be “Web, of course”. For the years 2000-2003 I’d vote for eCommerce, online applications and collaboration (like Google, eBay, Amazon and many others). And for the last 3 years, I would definitely pick online communities and blogs.\nBlogs are like tsunami that is changing the landscape of online content. There is nothing really new about what they are. Blog is user editable Web page, with very few features: implicit tracking of entries by creating calendar-based index of older entries, ability to add comments to the entries, limited form of categorization and tagging as well as some simple, blog-2-blog notification mechanisms (backtracks and pings). The only aspect in which blogs are different is simplicity of creating and running a blog. The same way as Google made searching for on-line content very easy and accessible, blogs are the very easy way how to create that content. Good content is one of the main reasons why people go online.\nTo have better idea about the magnitude of the effect, here are some numbers. According to David Sifry\n“… there is 50 million blogs out there (as of August 2006) and this number doubles every 6 months.”\nNow this is *some* growth - the blogosphere is 100 times bigger now than it was 3 years ago.\n“As of July 2006, about 175,000 new weblogs were created each day, which means that on average, there are more than 2 blogs created each second of each day. The total posting volume of the blogosphere continues to rise, showing about 1.6 Million postings per day, or about 18.6 posts per second. This is about double the volume of about a year ago.”\nIf you would expect that huge majority of the blogs is in English, you would be surprised. According to David, only approximately 40% blogs are in English, trailed by about 30% in Japanese and about 15% in Chinese. I wrote “about” as the number go up and down by few percent from month to month.\nI was quite surprised by really high ratio of Japanese blogs - high relatively to population size of Japan versus English speaking countries. Maybe the penetration of the market with very advanced video-internet capable computer-phones is responsible for the high number. I also believe for variety of reasons that large Chinese presence in cyberspace is a good thing, both for China as well the cyberspace. The “Internet services superpower” - India is probably under-represented and relatively invisible, hiding between English speaking blogs. Maybe because only few percent of huge Indian population has Internet access.\nThese numbers are simply overwhelming. Growth rate of the blogsphere is much higher than growth rate of the rest of WWW. Relative impact and weight of community driven web content will soon be larger than more traditional media with companies and organizations behind them (I consider both New York Times, CNN.com and Yahoo! being “traditional”, because the content is created by dedicated professionals).\nBut (there is always a “but”) - to really understand this new trend, it is important to have deeper look on the content, authors and audience of the blogs. A blog can be very different thing than a blog.\nThese basic questions help me to better understand and to organize my view of the blogospere:\n1) Who is the author ? # Is it single person providing his/her unique viewpoint or is it a community (such as Gizmodo, Lifehacker) ? Is it an organization ?\nMost of the growth (in absolute number of blogs) is coming from new individual bloggers, grouped around free hosting sites such as Blogspot, Livejournal, Blogging.com etc.\nCorporate blogs (see whitepaper) are also growing in popularity, both for internal and external use. Sometimes there is dedicated group of employees commenting on and discussing internal affairs on closed forum, sometimes the blog is public (such as this one ). Corporate blogs are representing much smaller percentage of the new blogs, but their contribution to the content is higher than from individuals. They also more often use premium hosting sites.\n2) What is the purpose / motivation for publishing ? # What is the benefit for the author ?\nSurprisingly large amount of blogs I’ve seen, did not have obvious motivation, rather than “because I can”. The main difference between publishing a Web and publishing a blog is very low barrier of entry. Almost everybody can blog. And as it looks like, almost everybody does.\nSome people start writing blogs because they are following the masses, joining the crowds - or because their friend Mike is blogging too. Some want to satisfy the innate human need to be heard / read, receive feedback and be more visible, be more important or just in order to become part of some community.\nTechnology related blogs often follow “meritocracy” principle from opensource movement. The more you contribute to a project, the higher is your influence and “rating” among your peers. Publishing and sharing your tips, tricks and insights on the blog is great way how to start contributing to the shared pool of knowledge.\nMany blogs are just plain public journals or on-line diaries. One can debate what is the value of putting your private journal to public consumption. IMHO, it takes some degree of exhibitionism to do that, assumed that you are honest with yourself and writing diary, not work of fiction about a non-existing person.\nYou have certainly seen (and likely ignored) many blogs that looked like they were created just to let the “steam off”, to express the the author’s frustrations. Aside from possible therapeutic effect for the owner, I find these of little interest to spend on them any time - unless you know the author personally. In this case, the journal blog provides unexpected insight (often quite unwelcome). In rare cases, the effect *can* positive.\nI have read nice dedication on one of the blogs (do not waste your time going there unless you speak Slovak) where 40+ new blog writer summarized his motives for blogging as:\n” I am a father of a blogger. From his blog, I have discovered a lot about his world and learned to understand him better. With this blog, I’d like to return him the favor”.\nLot’s of blogs are being created daily with one very specific purpose in mind: blogging for money. To do that, you need just two ingredients - large enough audience visiting your site and ads they can click on. The business model is simple: for every click on the displayed ads by your visitors, Google gets some tiny amount of money from advertisers and sends some percentage of this tiny amount of money to you. Which means you need many many many clicks to earn few bucks. And only very few sites actually get enough out of it, to use it as sustainable business model. Ads work best for focused community sites such as Gizmodo, with huge targeted audience. One nice example of site making money this way and still providing interesting content, created by single individual is Steve Pavlina.\nUnfortunately, there are few more \"business models\" for monetizing your blog - for example when a company pays seemingly unaffiliated bloggers to promote a product or service through “objective reviews”, but I do not consider this dubious business practices to be blogs (and certainly not worthy spending more time on).\nLegitimate blogs created by business tend to have better defined purpose. It costs money to pay people to blog and as business owner, you do not do it, unless it gives you back some value: new marketing channels, community building, evangelization of company/products/individuals or even direct sales. See Tim O’Reilly’s blog or http://www.joelonsoftware.com/ for a great example of valuable “personal business blog”\nQuite specific category of blogs are aspiring amateur writers and journalists, trying to do what they cannot do as their main job: writing and publishing fiction, novels, short stories, providing news and comments on events of interest. For these people, the blog is just easy, zero-barrier-of-entry delivery channel. Which leads directly to the next question: the content.\n3) What is the content/topics covered ? # Again, there is huge variety of all content imaginable out there - from blogs about Joe through blogs about world’s politics up to blogs about galaxies. The difference is degree of egocentrism, or in other words - how much is the personality and life of the blogger object of the blog. Usually (unless Joe Blogger is a celebrity) the more it is about Joe, the less interesting it is. Why would you (as a reader) care about Joe’s private life, what he did yesterday and what are his plans for vacation ?\nWell, you actually *may* care if:\n• Joe is somebody like George Clooney, Wayne Gretzky, Richard Feynman or Add-Your-Favorite-Celebrity-Here (guess who of the three mentioned is mine )\n• Joe happens to share something with you - it may be something good (like your secret passion for building model airplanes in scale 1:59 which very few people do), or something not so good (like lung cancer). By discovering a virtual acquaintance that shares your pain or passion, you feel less alone and may find something useful in how Joe copes with his situation.\n• you are compulsive watcher of reality shows and spend your own life by watching other people lives, regardless how boring they are (there must be some amount of people like that, otherwise the reality shows could not be so wildly popular )\n• Joe is your neighbor across the street and you have been wondering what business is this guy in to afford the new Lexus every year\n• Joe is your perspective employee or business partner, and you need to find out more about him before you employ him / sign a deal\nMany bloggers do not realize the hidden danger in last two cases - see these few examples to be warned.\n4) What audience is the blog for? What is the benefit for the readers ? # Surprisingly many bloggers seems not to think about their audience at all, which makes their blogs uninteresting and boring. At the other side of the spectrum are blogs addressing by choice controversial topics, written specifically to attract lots of readers and spark lots of heated online discussions. You can easily tell by the titles people use for their entries. This type of competing for the readership is very obvious when there is a ranking system on the server which sparks the competition or when there is a monetary incentive to have many readers - like using Google Ads. This has sometimes the very same effect as in journalism - previously good and respectable site degrades to some form of tabloid in chase for ad-clickers - I mean readers.\nWhat value do the blog readers gets out of blog ? I do not dare to make any guess for the others. There must be something in it for many different people, otherwise there would be no large audiences. Basic motivation can be curiosity and leisure - passive content consumption - pleasant way how to spend time. A kind of new TV, with much more control over what you read/watch/listen to (considering the increasingly popular audioblogs aka podcasts and videoblogs).\nFor me personally main value areas I get out of reading blogs and community driven content repositories are:\n1) learning and problem solving # You may not always find answer you are looking for in the “traditional” professional Website. Whether I need need an explanation why am I getting mysterious SQL Server 2005 error message or how to get iMovie to recognize MPEG file from Sony HDD digital camera, my best bet usually are forums, Wiki’s and blogs. None of them is clearly superior, and blogs have their perfect place in the infospace.\nCompared to Wikis and Forums, Blogs are more personal,with more narrow focus. Which means once you find a blogger that works on similar problem or in the same area, you have best possible match. In Forums, many people contribute and create topics. This leads to wider area coverage and to more ideas, but also to less coherence and (in order to find something) more clutter for the reader to work through. Blogs are less formal and less structured than Wiki’s. It leads people to providing and sharing content more easily. I have less worries and things to consider when I add new entry on my blog than when I am editing a Wiki page, possibly modifying somebody else’s contribution. There is more personal touch in blog and little need for consensus as with Wiki. Blogs are also more convenient for the authors - content for the blog can be created offline and uploaded, edited directly in browser or even sent through email, whereas Wiki and Forum must be accessed only through browser.\n2) navigation guide and discovery # It happened many times with books: I have found blog about books, where the blog author highly rated several books that I liked a lot as well. On the same site, I have also found recommended other books, I never heard about before. After reading them, I loved them. This is how I found Red Dwarf series, the Frederik Pohl’s Heechee saga as well as Andrzej Sapkowski fantasy masterwork . Similar idea are Amazon “recommends” and Amazon user book lists, but there is bigger chance of commercial motivation behind book great 5-star review and also less visibility to the personality behind the recommendation(s).\n3) filter … # something like SQL View, limiting the data to what is relevant. It is one of the ways how to deal with information overload. Many people browse the Web and blog on nuggets they discover. If you find and pick right person, his/her trail may be very interesting to follow.\nThe bookmark community sites such as del.icio.us, digg.com, reddit.com are doing something very similar, but filtering “by statistics” rather by interest. They are usually best bet to discover trends, fashion waves and new fads, but if your information taste differs a lot from Average User, you may be better off with finding few virtual buddies that are more like you and follow their trails - through their blogs or bookmark collections. Chances are, they are reading digg or reddit and will report their findings anyway.\nBlogs++ # With all the millions blogs in existence, what is the point of adding another drop to the sea of blogs ? What is the motivation and intention of the author of this one ? Where in the classification should this blog fit in ?\nThis is an individual blog. It does not represent standpoint of the company I am affiliated with. There certainly is strong alignment between many of my company values, views and visions and my values, goals and visions - which is why I work there - but this is not meant to be our official PR.\nThe topics reflect my interests and are therefore (mostly) technology and cyberspace related. From “real life” I am commenting on very few topics, e.g. books and personal productivity / personal development (aka “lifehacks”), all of which are quite close to technology and cyberspace. I have all intentions to avoid easily inflammable topics (such as politics or religion) unless it is “flamewar” about technology (for example Linux vs. Windows vs. Mac or .NET contra Java - be my guests!).\nIt is not a personal journal. It is subjective - as every blog is - but I’ll try my best to stay focused on the topics other than my personal life. No pictures of the kids or family vacations here. They are some out here on the Web, but audience is limited to mostly family only. Unless you know me quite well, it would not really interest you anyway.\nWriting a blog takes a lot of time. This blog is my spare time activity. While ago, I found out that for me personally writing is the best way how to organize my thoughts, pretty much on anything. During last two-three years, more and more of this writing was happening on computer. So in addition of many paper notebooks, I have created many small files, in variety of formats, spread across variety of computers. As many users of multiple computers, only way how to have my stuff available was to store it somewhere on-line. I tried several offline+synchronization strategies too, with mixed results, but that is a different topic, I’ll get back to it.\nSo my files as well as electronic trace of interesting topics and places have been stored online for over two years now.\nWhat benefit do I expect to get out of making my e-Stuff publicly accessible ? # Several benefits, in fact:\n- quality of content. # I saw huge jump in quality when I started to write things down compared to just thinking about them. Writing forced me to formulate my thoughts much more precisely and writing/typing slowed me down enough to spot obvious problems. I hope for similar effect when going from writing privately to writing publicly. Chance of a feedback and possibility of an audience will (hopefully) force me to improve my communication skills, upgrade my English grammar and vocabulary and communicate more clearly. Time will show if it will indeed happen …\n- accessibility # If something is easily accessible for everybody, it is easily accessible for myself as well - diligence in active processing of the content # Responsibility of public blog will hopefully help to overcome laziness. It happens all the time: I have interesting idea or observation, but because I am lazy, I just fire off an email to myself with 3 cryptic words or write them down on piece of paper. Week later, nothing makes sense any more, and idea is gone. If I’d spend 5 more minutes on making it a short blog entry, it could have been still there. With my Mac virtually always with me, I can do that from any place\n- learning on own mistakes # You can never learn from a mistake unless you find out you’ve made one first. And nobody will give any feedback, unless they know what you are doing …\n- synchronicity and serendipity # One cannot rely on it, but I have seen evidence of it too many times to ignore it. Just trying to increasing the chances of any of that happening again, is worth the effort.\nScrolling back to top in ecto , I think that the very first skill I have to master will be how to write shorter entries :-).\nIf you managed to read until here, thanks for your time. See you soon.\n","date":"August 22, 2006","externalUrl":null,"permalink":"/posts/2006-08-22-on-blogs-bloggers-blogging/","section":"Posts","summary":"If you would ask me to pick one technology phenomenon that had the largest impact on and was the most characteristic for the technology during the years 1995-2000, my answer would be “Web, of course”. For the years 2000-2003 I’d vote for eCommerce, online applications and collaboration (like Google, eBay, Amazon and many others). And for the last 3 years, I would definitely pick online communities and blogs.\nBlogs are like tsunami that is changing the landscape of online content. There is nothing really new about what they are. Blog is user editable Web page, with very few features: implicit tracking of entries by creating calendar-based index of older entries, ability to add comments to the entries, limited form of categorization and tagging as well as some simple, blog-2-blog notification mechanisms (backtracks and pings). The only aspect in which blogs are different is simplicity of creating and running a blog. The same way as Google made searching for on-line content very easy and accessible, blogs are the very easy way how to create that content. Good content is one of the main reasons why people go online.\n","title":"On blogs, bloggers, blogging","type":"post"},{"content":"Since R\u0026amp;K published the The Book, the title above became de-facto standard way how to start anything. Which is one of the two reasons why I used it as title for this very first entry. The second reason is that the friendly folks from to Wordpress.com have created the title and the first blog entry for me.\n","date":"August 19, 2006","externalUrl":null,"permalink":"/posts/2006-08-19-hello-world-2/","section":"Posts","summary":"Since R\u0026K published the The Book, the title above became de-facto standard way how to start anything. Which is one of the two reasons why I used it as title for this very first entry. The second reason is that the friendly folks from to Wordpress.com have created the title and the first blog entry for me.\n","title":"Hello world!","type":"post"}]