Skip to main content

a silhouette of a person's head and shoulders, used as a default avatar

opendev: OpenStack Foundation failed to learn the lesson

Yesterday I got an invitation to the opendev conference (September 7-8, 2017) from the OpenStack foundation. The conference is about edge computing. 

While the topic itself is very interesting I was surprised that the opendev will be held in the U.S. (San Francisco, CA). I thought the foundation would have learned a lesson from the Boston summit this year. And as far as I understood it they decided to have currently no summits in the U.S. anymore until the political climate changed to allow risk free travel for all community members (see Kurt Garloff's talk at DOST around 8:45min). But it seems this applies only to the summits, very inconsistent! Some people would call it slightly duplicitous.

In light of the OpenStack Foundation's decision I'm still proud about the Ceph community. They decided with a clear statement to not held any event in the U.S. that requires travel for community members from foreign countries while there is the risk to potentially suffer harassment, digital privacy violations, or rejection at the border.

a silhouette of a person's head and shoulders, used as a default avatar

the avatar of Francisco J. Arias

the avatar of Francisco J. Arias

Arduino para Niños

Hace un par de semanas iniciamos un pequeño proyecto junto a mi hija. La idea era encontrar algo que nos permitiése divertirnos y compartir tiempo juntos, si además de lo anterior se aprende algo, tanto mejor. Entonces se me ocurrió la idea de enseñarle experimentos usando Arduino, algo de electrónica muy (pero muy) básica y un toque de programación.

Así nació este proyecto de ir grabando en video y publicando sus experimentos. El trabajo se presenta en formato simplificado: arduino por niños y para niños. Ella tiene apenas 10 años y se mostró muy entusiasmada. En el "detrás de cámaras" armó un arreglo de 8 leds con alimentación común y otro de 4 leds con alimentación individual, después de aprender el clásico "Hola Mundo" de Arduino usando sólo un led. Para las próximas entregas empezaremos con sensores y condiciones. La idea final (que ella aún desconoce, al más puro estilo del Dr. Manhattan xD) es construir un repele-gatos y también un pequeño vehículo.

Los invito entonces a difundir y compartir ;-) (Enlace video)



the avatar of Federico Mena-Quintero

Legacy Systems as Old Cities

I just realized that I only tweeted about this a couple of months ago, but never blogged about it. Shame on me!

I wrote an article, Legacy Systems as Old Cities, for The Recompiler magazine. Is GNOME, now at 20 years old, legacy software? Is it different from mainframe software because "everyone" can change it? Does long-lived software have the same patterns of change as cities and physical artifacts? Can we learn from the building trades and urbanism for maintaining software in the long term? Could we turn legacy software into a good legacy?

You can read the article here.

Also, let me take this opportunity to recommend The Recompiler magazine. It is the most enjoyable technical publication I read. Their podcast is also excellent!

Update 2017/06/10 - Spanish version of the article, Los Sistemas Heredados como Ciudades Viejas

a silhouette of a person's head and shoulders, used as a default avatar

openSUSE Conference 2017

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


Конференция была открыта докладом Матиаса о LiMux. Краткая история проекта, его взлет, надежды и его падение… Явный пример того, на сколько опасны могут быть политики, пользующиеся властью для удовлетворения собственных предпочтений, и закрывающие глаза на интересы и желания населения. В настоящий момент я как раз работаю над этим проектом в администриции Мюнхена.

На конференции я снова встретился с Дмитрием, занимающимся проектом invis и продвижением Free Software решений на базе 1C в Германии. Беседовали о русскоязычном сообществе openSUSE, и о причинах его столь плачевного состояния. Я очень надеюсь, что сообществу получится преодалеть существующие проблемы и оно снова возьмет курс на развитие, как было в 2008-2010 годах.

Познакомился с Денисом Кондратенко из Киева и его женой. Очень приятная пара. Денис рассказывал о Ceph и EKG в openSUSE, а также о методах обработки метаданных в Elasticsearch. Мой личный опыт использования Elasticsearch ограничивается только BigData/Hadoop, поэтому и тут удалось узнать что-то новое.

Много новых иновационных идей было услышано от Ричарда. Он уже давно стал openSUSE evangelist’ом; его доклады об OBS или openQA можно услышать практически на каждой европейской Free Software конференции, посвященной GNU/Linux. Я всем советую посмотреть его доклад о Containerised Application.


Одним из спонсоров конференции в этом году стал fedora project. Fedora уже не первый год использует нашу систему openQA для автоматического тестирования linux-систем, а сотрудники RedHat уже во второй раз читают свои доклады на openSUSE Conference. В этом году это был доклад How semantic analysis of C and C++ ELF binaries can be used to analyze ABI changes, в прошлом году это были Enforcement of a system-wide crypto policy и Testing complex software in CI.

В общем, как и обычно, конферениция оставила приятное впечатление (пару фоток можно найти тут). И хотя в этом году она длилась всего 3 дня вместо 5, как в прошлом, информации для размышления я пролучил придостаточно. Её посещение в этом году не стоило мне ничего. Спасибо за это TSP. В следующем году она пройдет в Праге, куда я планирую поехать с семьей. Возможно там я встречусь и с теми, кто читает сейчас эти стоки 😉

the avatar of Federico Mena-Quintero

Setting Alt-Tab behavior in gnome-shell

After updating my distro a few months ago, I somehow lost my tweaks to the Alt-Tab behavior in gnome-shell.

The default is to have Alt-Tab switch you between applications in the current workspace. One can use Alt-backtick (or whatever key you have above Tab) to switch between windows in the current application.

I prefer a Windows-like setup, where Alt-Tab switches between windows in the current workspace, regardless of the application to which they belong.

Many moons ago there was a gnome-shell extension to change this behavior, but these days (GNOME 3.24) it can be done without extensions. It is a bit convoluted.

With the GUI

If you are using X instead of Wayland, this works:

  1. Unset the Switch applications command. To do this, run gnome-control-center, go to Keyboard, and find the Switch applications command. Click on it, and hit Backspace in the dialog that prompts you for the keyboard shortcut. Click on the Set button.

  2. Set the Switch windows command. While still in the Keyboard settings, find the Switch windows command. Click on it, and hit Alt-Tab. Click Set.

That should be all you need, unless you are in Wayland. In that case, you need to do it on the command line.

With the command line, or in Wayland

The kind people on #gnome-hackers tell me that as of GNOME 3.24, changing Alt-Tab doesn't work on Wayland as in (2) above, because the compositor captures the Alt-Tab key when you type it inside the dialog that prompts you for a keyboard shortcut. In that case, you have to change the configuration keys directly instead of using the GUI:

gsettings set org.gnome.desktop.wm.keybindings switch-applications "[]"
gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward "[]"
gsettings set org.gnome.desktop.wm.keybindings switch-windows "['<Alt>Tab', '<Super>Tab']"
gsettings set org.gnome.desktop.wm.keybindings switch-windows-backward  "['<Alt><Shift>Tab', '<Super><Shift>Tab']"

Of course the above also works in X, too.

Changing windows across all workspaces

If you'd like to switch between windows in all workspaces, rather than in the current workspace, find the org.gnome.shell.window-switcher current-workspace-only GSettings key and change it. You can do this in dconf-editor, or on the command line with

gsettings set org.gnome.shell.window-switcher current-workspace-only true

a silhouette of a person's head and shoulders, used as a default avatar

Packaging MediaWiki extensions

As part of the work for the openSUSE wiki upgrade and move, I had to package a bunch of MediaWiki extensions. We'll use the MediaWiki 1.27.x LTS release, which means the extensions need to work with this version.

When it comes to packaging, there are three categories of extensions:

The Good

These extensions are hosted on phabricator.wikimedia.org, and you can easily download a tarball matching your MediaWiki version using the "Download snapshot" link on the extension page.

Packaging these extensions is easy - just unpack the tarball and copy/package everything to the extension directory.

These extensions are standardized enough to use a spec file template - usually I only had to adjust the extension name, tarball name and version. Speaking of the version - most extensions don't have explicit version numbers, so I decided to use the tarball date instead.

An example for this category is Auth_remoteuser (extension page, package) which we use to keep the "nice" wiki login form.

The Bad

These extensions are hosted on GitHub and typically only have a "master" branch. They usually still work with MediaWiki 1.27.x, but there's a small risk that they require features added in newer MediaWiki versions, and this risk will grow over time.

On the packaging side, they are as easy as the "good" extensions.

An example is the ParamProcessor extension (extension page, package) which is needed by the Maps extension

The Ugly

These extensions can be hosted on phabricator.mediawiki.org or GitHub, so there are "god ugly" and "bad ugly" extensions ;-) The thing that makes packaging really ugly is that they don't include all the code they need. Instead, you have to download the missing parts with composer.

composer works fine in a "real" system, but makes packaging hard. Running it from the spec will obviously fail because OBS doesn't allow network connections while building a package (and even if it's annoying in this case, not having network access during build is a good thing[tm]).

My solution is a little script that unpacks the extension tarball and runs "composer install --no-dev" inside the extension directory. The most important part is the "--no-dev" parameter because that avoids lots of superfluous things. Afterwards, I build a tarball from the "vendor" directory and add it to the package.

Yeah, I know that's not nice - guess why I named this section "The Ugly" ;-)

One of the packages that need a "composer install" run is the GitHub extension (extension page, package including script to run composer).

Luckily, "ugly" only applies to packaging. The extensions and their maintainers are for sure not ugly - for example, the maintainer of the GitHub extension was very fast in fixing a bug :-)

the avatar of Sankar P

golang range Tickers

Update: Please use the playground/gist urls for reading code. Blogger's code formatting is terrible and does not support embedding gists either.

Yesterday Praveen sent me an interesting piece of golang code. Read the following code and tell what the answer will be:

===
type LED struct {
state  bool
ticker *time.Ticker
}

func toggle(led *LED) {
led.state = !led.state
}

func looper(led *LED) {
for range led.ticker.C {
toggle(led)
}
}

func main() {

fmt.Println("Initial number of GoRoutines: ", runtime.NumGoroutine())

led := &LED{state: true, ticker: time.NewTicker(time.Millisecond * 500)}
go looper(led)
fmt.Println("Number of GoRoutines after a call to looper: ", runtime.NumGoroutine())

time.Sleep(2 * time.Second)

led.ticker.Stop()
fmt.Println("Number of GoRoutines after stopping the ticker: ", runtime.NumGoroutine())

runtime.GC()
fmt.Println("Number of GoRoutines after gc: ", runtime.NumGoroutine())

}
===


Golang playground URL: https://play.golang.org/p/1as5QN1r2c
Gist URL: https://gist.github.com/psankar/8af76ba183b0203ec141bca8156f5955

I will explain roughly what the code is doing.

There is a LED struct which has a Ticker and a state variable. While creating an instance of the led struct, we initialise the state and the Ticker.  There is a looper function will toggle the state, whenever the Ticker fires an event.

Now when the program is launched, there will be one goroutine (the initial main thread). After we call looper in a goroutine, the goroutineCount will be 2. Now, comes the tricky part. We stop the Ticker, after a particular amount of time. We even call the gc.

It was observed by Praveen that this piece of code was leaking go routines and the number of go routines was never going down, inspite of the Ticker getting stopped.

The reason why the leakage is happening is because, the "range" loop is never exiting. If the range loop was on a channel, you could "close" it. The ticker.C channel however is a receive only channel and you cannot close it.

How do we fix this, so that none of the goroutines are leaking ? If you have watched the talks, golang concurrency patterns by Rob Pike and Advanced golang concurrency patterns by Sameer Ajmani, then you will realise that it is quite easy to add another parameter to the looper function, which could just exit the loop. So the updated code will be:

===
type LED struct {
state  bool
ticker *time.Ticker
}

func toggle(led *LED) {
led.state = !led.state
}

func looper(led *LED) {
for range led.ticker.C {
toggle(led)
}
}

func looper2(led *LED, q chan bool) {
for {
select {
case <-led.ticker.C:
toggle(led)
case <-q:
fmt.Println("Exiting the goroutine")
return
}
}
}

func main() {

fmt.Println("Initial number of GoRoutines: ", runtime.NumGoroutine())

led := &LED{state: true, ticker: time.NewTicker(time.Millisecond * 500)}
q := make(chan bool)
go looper2(led, q)
// go looper(led)
fmt.Println("Number of GoRoutines after a call to looper: ", runtime.NumGoroutine())

time.Sleep(2 * time.Second)

led.ticker.Stop()
fmt.Println("Number of GoRoutines after stopping the ticker: ", runtime.NumGoroutine())

q <- true
        fmt.Println("Number of GoRoutines after sending a message on the quit channel: ", runtime.NumGoroutine())
}
===


Playground URL: https://play.golang.org/p/NlWbyHLHvA
Gist URL: https://gist.github.com/psankar/4e5b2e563038ce3e9c17eb208c76168a

Let me know if you have any comments.

a silhouette of a person's head and shoulders, used as a default avatar

Langkah Sederhana Upgrade Leap 42.1 ke 42.2

Pada kesempatan kali ini Saya mencoba untuk membuat langkah sederhana untuk memutakhirkan versi (upgrade) openSUSE Leap 42.1 menjadi 42.2. Untuk penjelasan lebih detail, Anda bisa mengunjungi panduan upgrade official dari openSUSE di link ini. Sedangkan pada tutorial ini, Saya hanya akan mencoba untuk menjelaskan langkah yang sangat sederhana untuk melakukan proses upgrade. Langkah ini telah saya lakukan dan berhasil. Berikut langkah – langkahnya.

  1. Pastikan sistem Anda telah dilakukan update, jika belum Anda bisa melakukannya dengan melalui Software Manager atau dengan menggunakan terminal (akses root) dengan mengetik zypper up.
  2. Lakukan backup repository sekarang dengan mengetik cp -Rv /etc/zypp/repos.d /etc/zypp/repos.d.old.
  3. Hapus repositori yang tidak diperlukan melalui aplikasi YaST2 kemudian pilih Software Repositories. Cara ini bisa dilakukan juga dengan melalui terminal, namun sebagaimana pada kesepakatan awal bahwa Saya hanya akan menjelaskan langkah yang sederhana dan mudah.
    Agar lebih mudah ketika melakukan upgrade, berikut repositori yang tidak Saya hapus.
    * OSS
    * Non OSS
    * OSS Updates
    * Packman
  4. Ubah angka versi rilis pada repositori yang ada menjadi 42.2 (sebelumnya 42.1)
  5. Kembali ke terminal, lakukan refresh dengan mengetik zypper ref.
  6. Unduh paket dari repositori terbaru dengan mengetik zypper dup –download-only.
  7. Setelah proses unduh selesai, logout dari sistem.
  8. Tekan Ctrl+Alt+F1 untuk masuk ke mode teks dan login sebagai root
  9. Ubah runlevel ke 3 dengan mengetik init 3.
  10. Terakhir ketik zypper –no-refresh dup untuk melakukan proses upgrade.

Proses upgrade membutuhkan beberapa menit. setelah proses upgrade selesai dan tidak terjadi kendala Anda bisa melakukan reboot pada sistem kemudian setelah login Anda bisa mengecek versi dari sistem dengan melalui terminal dengan mengetik lsb_release -a.

Keyword : openSUSE 42.1, openSUSE 42.2, Leap, Update, Upgrade, Instalasi