ProgressUI with Firefox integration
You can order your computer to turn of or reboot, when some tasks are done. Currently only Firefox’s download manager is supported. I wrote also some simple programs to demonstrate, how ProgressUI works, but only Firefox is big application integrated with my tool. Integration needs extra extension to be installed.
In this movie, I download Sintel (open movie) and order ProgressUI to start playing this movie, when download completes.
This project still have some major bugs, but I try to solve them in near future.
You can download ProgresUI from sourceforge.net.
Understanding io.Reader in Go
Recently, I was trying to learn how the io.Reader interface works in Go and implement my own custom reader. Before implementing a custom Reader let’s understand what they are.
Readers: What are they?
Readers are interfaces or classes that are implemented in various programming languages. Usually, readers take in an input interface that can usually be represented as an array and a length. The reader returns another stream that is usually a cut to the length of the original input. Readers are implemented in various programming languages as following:
- Java: readers are implemented by the interface java.io.Reader that implements read(char[], int, int) and close().
- C++: readers are implemented by the istream where the read function is depicted as follows istream& read (char* s, streamsize n);
- Go: readers are implemented by the io.Reader interface which has Read(p []byte) error.
In the above examples, readers in various programming language do the same thing; they read from the input stream and make a copy of the same into the char / byte array that is provided to the Read function.
Implementing custom Reader in Go
In this example, we will implement a reader that will add the capitalize the characters in the resulting byte array to which we want to copy the result into.
Note: This may or may not be suitable for production but is an example. I have also not seen examples of modifying the string.
Readers in Go need to implement the following language
type Reader interface {
Read(p []byte) (n int, err error)
}
We will use 2 ways to implement the reader:
- By natively implementing the Read function.
- Using an already existing reader (strings.Reader)
Native implementation of the Read function
package main
import (
"bytes"
"fmt"
"io"
"log"
"time"
)
// CapitalizeReader is a reader that implements io.Reader
// It read the bytes from a particular position and returns the number
// of bytes that are read. If an error is thrown, all the errors are thrown
// as it is.
type CapitalizeReader struct {
b []byte
i int
}
// Read implements the function for CapitalizeReader.
// p is the []byte where the data is copied to.
// n is the number of bytes that are read and if there is an error it is
// returned along with the bytes that are read.
func (cr *CapitalizeReader) Read(p []byte) (n int, err error) {
// By default, the size of the
// if the number of bytes are less than the bytes to be read, then we assign it.
var l int = len(p)
if len(cr.b)-cr.i < len(p) {
l = len(cr.b) - cr.i
}
var t []byte = cr.b[cr.i : cr.i+l]
n = copy(t, cr.b[cr.i:])
cr.i += n
t = bytes.ToUpper(t)
n = copy(p, t)
// If the bytes read is less than the length of input byte slice, return the number of bytes
// and io.EOF; it is different from Go's byte reader implementation where it will copy everything
// and always return 0, io.EOF in the next implementation.
// Ref: https://golang.org/src/bytes/reader.go?s=1154:1204#L30
if l < len(p) {
return n, io.EOF
}
return n, nil
}
// NewCapitalizeReader takes in a string and returns a reader.
// Store string as a slice of bytes so that we can read bytes
// and uppercase it on read.
func NewCapitalizeReader(s string) *CapitalizeReader {
return &CapitalizeReader{b: []byte(s), i: 0}
}
func main() {
str := "hello world"
cr := NewCapitalizeReader(str)
fmt.Println("length of the string: ", str, " is ", len(str))
var b = make([]byte, 2)
for {
time.Sleep(200 * time.Millisecond)
n, err := cr.Read(b)
fmt.Println(n, "\t", n, "\t", string(b[:n]))
if err != nil {
if err == io.EOF {
break
}
log.Fatal(err)
}
}
bytes.NewReader()
}
Using an already existing reader (strings.Reader)
The below example explains how to use an underlying Reader. Go does this quite often. For example, we have the LimitReader (https://golang.org/pkg/io/#LimitedReader). The LimitReader accepts a Reader and assigns this reader as the underlying reader. Once a set number of bytes are reached, it will return an EOF even if the underlying reader has not reached an EOF. This example uses strings.Reader as the underlying Reader.
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"log"
"strings"
"unicode"
)
// CapitalizeReader is a reader that implements io.Reader
// The underlying reader is a strings.Reader that is used to
// read the bytes from a particular position and returns the number
// of bytes that are read. All the errors are thrown
// as it is.
type CapitalizeReader struct {
// sr is the underlying reader to use the reading operations for.
sr *strings.Reader
// offset is the index from where the string is read into the given []byte slice
offset int64
}
// Read implements the function for CapitalizeReader
// p is the []byte where the data is copied to.
// n is the number of bytes that are read and if there is an error it is
// returned along with the bytes that are read.
func (cr *CapitalizeReader) Read(p []byte) (n int, err error) {
// create a new array where modifications will be made
var t = make([]byte, len(p))
n, err = cr.sr.ReadAt(t, cr.offset)
// track the offset by number of bytes that were read
cr.offset = cr.offset + int64(n)
t = bytes.ToUpper(t)
// copy to the provided array only when all the operations are done.
// io.Reader interface explicitly specifies that p should not be held by Read.
copy(p, t)
return
}
// NewCapitalizedReader takes in a string and returns a reader.
// offset is set to 0 as that is we want to read from.
func NewCapitalizeReader(s string) *CapitalizeReader {
return &CapitalizeReader{sr: strings.NewReader(s), offset: 0}
}
func main() {
str := "hello world"
cr := NewCapitalizeReader(str)
fmt.Println("length of the string: ", str, " is ", len(str))
var b = make([]byte, 2)
for {
n, err := cr.Read(b)
// Notice that we read by slice b[:n] even in the case of error
// This is because io.EOF can happen we can still have a byte that is read and
// it is easy to miss it out.
fmt.Println(n, "\t", n, "\t", string(b[:n]))
if err != nil {
if err == io.EOF {
// exit gracefully with in case of io.EOF
break
}
// For all other errors exit with a non-zero exit code.
log.Fatal(err)
}
}
}
Summary
- Readers have a similar interface in various programming languages.
- Readers in Go can be implemented natively by implementing the Read(p []byte) (int, eror) method for any struct.
- Readers in Go can also have a backing or an underlying reader that can be used to implement a new reader. This new reader can be limit or enhance the capability of the underlying reader. An example of this is the LimitReader in Go
openSUSE Tumbleweed – Review of the week 2021/24
Dear Tumbleweed users and hackers,
This week we have seen a steady stream of snapshots being published. A full 6 snapshots made it out onto the mirrors (0611, 0612, 01613, 0614, 0615, and 0616).
The main changes in those snapshot included:
- Mozilla Firefox 89.0
- Linux kernel 5.12.10
- python3x packages no longer provided ‘python’ as a symbol to not confuse the python2 stacks
- KDE Gear 21.04.2
- KDE Frameworks 5.83.0
- GNOME 40.2
This matches pretty much what was promised to come during last week’s review. A few things still take a bit more time, and more things have shown up in the staging areas:
- Linux kernel 5.12.12
- KDE Plasma 5.22.1
- Cinnamon 5.0
- systemd 248
How to test things with openQA without running your own instance
Wait what?
Yes, there are couple of ways for you, the user, the contributor, the amazing human being who wants to improve the software that is used by millions, to write automated tests and have bots doing all the work for you, once you’ve signed a binding contract with the blood of an unicorn, and have obtained api keys for our public https://openqa.opensuse.org instance.
For now I will leave out the details on how to get those, but will rather point you to the #factory irc channel (or dischord), where you can get in touch with current admins, whom will be able to guide you better in the process.
I have the keys
You should get operator keys and they would look like this (more or less):
[openqa.opensuse.org]
key = 45ABCEB4562ACB04
secret = 4BA0003086C4CB95

Now let’s do this
I will assume that you’re using openSUSE Tumbleweed, instructions are similar for Leap, but if you’re looking for something more esoteric, check the bootstraping guide
Bring up a terminal or your favorite package manager, and install openQA-client, it will pull almost everything you will need
zypper in openQA-client
Once we’re here, we’ve gotta clone the git repo from the tests being ran in openqa.opensuse.org, to do that let’s go to a directory; let’s call it
Skynet and create it in our user’s home. My user’s home is /home/foursixnine \o/ and use git to clone the test repository:
https://github.com/os-autoinst/os-autoinst-distri-opensuse/.
cd $HOME
mkdir Skynet
cd Skynet
git clone https://github.com/os-autoinst/os-autoinst-distri-opensuse/
Now since we already cloned the test distribution, and also got the openQA client installed, all there is to do is:
1 - Hacking & Commiting 2 - Scheduling a test run
At this point we can do #1 fairly easy, but #2 needs a bit of a push (no pun intended), this is where we will need the API keys that we requested, in the beginning.
We will rely for now, on openqa-clone-custom-git-refspec which reads configuration parameters from “$OPENQA_CONFIG/client.conf”, “~/.config/openqa/client.conf”
and “/etc/openqa/client.conf” (you can run openqa-cli –help to get more detailed info on this), for now open up your favorite editor and let’s create the directories
and files we’ll need
mkdir ~/.config/openqa
$EDITOR ~/.config/openqa/client.conf
And paste the API keys you already have, you you will be able to post and create jobs on the public instance!
Let’s get hacking

This part is pretty straightforward once you’ve looked at $HOME/Skynet/os-autoinst-distri-opensuse.
For this round, let’s say we want to also test chrome, in incognito mode. By looking at chrome’s help we know that the --incognito is a thing
So let’s go to where all the tests are, edit, commit and push our changes
Remember to set up your fork, however if you want to make your life easier use hub you can find it in the repos too!
cd $HOME/Skynet/os-autoinst-distri-opensuse
vim tests/x11/chrome.pm
git commit -m "Message goes here" tests/x11/chrome.pm
git push $REMOTE
openqa-clone-custom-git-refspec \
https://github.com/foursixnine/os-autoinst-distri-opensuse/tree/test_incognito_in_chrome \
https://openqa.opensuse.org/tests/1792294 \
SCHEDULE=tests/installation/bootloader_start,tests/boot/boot_to_desktop,tests/console/consoletest_setup,tests/x11/chrome \
BUILD=0 \
TEST=openQA-WORKSHOP-ALL-CAPS
In the end you will end up with an URL https://openqa.opensuse.org/t1793764, and you will get emails from travis if something is going wrong
Digest of YaST Development Sprint 125
Time flies and another two weeks of YaST development have passed. As in the previous report, we have to mention we invested quite some time learning and experimenting with technologies that will shape the role of YaST in particular and Linux installers in general in the future. But we also had time to fix quite some bugs and to make progress in several features, like:
- Simplified support for hibernation
- Make network forwarding configurable in the installer
- Improved tabs in graphical mode
- Progress in the rewrite of yast2-users, including AutoYaST
Hibernate All Systems!
Funnily enough, the first aspect we want to report about is not a feature we developed, but one we reverted. Back in November we reported a new feature in the installer to propose hibernation only on real hardware (ie. not on virtual machines) and only if the product’s configuration specifies hibernation is desired. Time has proved that the usage of hibernation in real world scenarios goes further than expected back then. For example, hibernation is used on virtual servers deployed on top of some cloud-based infrastructures, as part of a technique to save power and money. The existence of that kind of creative scenarios makes it very hard to predict when hibernation is wanted and when not. So YaST will go back to its previous behavior of proposing hibernation always if the technical conditions are met, no matter which product is being installed or in which environment. The change will be available as an installer self-update for SLE-15-SP3.
Better Default Network Configuration
Despite the hibernation affair, we don’t give up in our attempts to make smart selections in the installer. As you may know, YaST allows to tweak the network configuration during installation. Among many other things, it allows to configure the status of IP forwarding. But we want YaST to propose a correct default value for those settings without requiring user intervention. In the cases of openSUSE MicroOS and SLE Micro that means enabling forwarding by default, since is needed for such systems to work properly. So we made that configurable per product and adjusted the corresponding configuration for those container-based solutions.
Prettier Tabs
Beyond the installer, we also invested some time in something we really wanted to put our hands on - improving the look&feel of the YaST tabs in graphical mode. The description of this pull request includes a good description of the problems (with a link to the original issue in which they were discussed), a technical explanation of the solution and, of course, many screenshots!
New Users Management to Arrive Soon
Last but not least, we continue our small project to rewrite big parts of the users management in YaST. We implemented support for some aspects that were still based on ancient Perl code and we are getting rid of all the legacy parts involved in (auto)installation. If everything goes as expected, next sprint will see the new user management land in the installation process of openSUSE Tumbleweed.
See you soon
We hope you are already enjoying openSUSE Leap 15.3 and ready for the openSUSE Virtual Conference 2021. Meanwhile, we keep working to make YaST a little bit better every day thanks to your feedback. See you around and have a lot of fun!
ProgressUI
Recently, I nearly create ProgressUI – tool to setup triggers (condition/action pair) related to task of programs. Currently It’s very simple, because it supports only one kind of action – running external program. User must also type program name and parameters. In future, we would read .desktop files and allow to select from dropdown list (for example). Also, I will add possibility to invoke DBus method and allow to define method name/path/etc. in special files, so user could also select method. Also, I must enhance my set of tools in other ways – for example allowing to send watch fd to daemon, so It could report exit code of application.
In terms related to libgreattao, I added functions, possibility to invoke it and signals. Functions not working properly yet, so doing special thinks like allowing to create multi-level menu is not possible. Signals are templates, but treated in different way – they could been processed multiple times without need to give unique path. It also do not work as expected since it created many not needed entities, but needed for templates. Simplicity is boring.
See: https://www.youtube.com/watch?v=sm04e2N5AcU&t=9s
And yet, I created patron (in patreon.com) page. See: https://www.patreon.com/easylinux?fan_landing=true
Survey For openSUSE Leap 15.3 Release Closes
Our survey about the release of openSUSE Leap 15.3 has ended and the results will be discussed in a release retrospective at the openSUSE Conference in the coming days.
“I’d like to give big thanks to all of those who participated…,” wrote release manager Lubos Kocman in an email. “We’ve received 605 responses, which is almost 200 more than in 15.2. I’m grateful for the increased participation as it shows us that it makes sense to have this type of feedback loop.”
Kocman will give a talk at the openSUSE Conference on June 19 at 09:00 UTC and discuss the results.
Project members and participants of the conference and survey are encouraged to join.
“We’ll schedule some more public rounds on meet.o.o as well, as you can’t review all of (the) feedback (plus) create action items in a single session,” he wrote.
For those interested in the raw data from the survey, it is available on the wiki page.
openSUSE Leap 15.3 – A stable base with modern applications
Its interesting to watch Youtube reviews for openSUSE Leap 15.3. One of the main critics is that it doesn’t offer the latest KDE and GNOME desktop versions. “The software is quite old.” Yes, that is not very interesting for a reviewer. Because as a reviewer, you like to point out what is new. And what is exiting. And the goal of openSUSE Leap 15.3 is to not be exciting. The goal is to be stable.
openSUSE Leap and SUSE Linux Enterprise have moved closer together over the last few years. I remember all the effort that has been put into making sure that the codebase for the base packages of openSUSE Leap and SUSE Linux Enterprise were similar. In may 2015 (yes, that is a while ago) Richard Brown announced that the latest SUSE Enterprise Sources where now available in the Open Build Service and he presented the vision for a new stable release version, which would be named openSUSE Leap. But after that, there was still a lot of work. It took a couple of releases (42.1, 42.2, 42.3 and then 15) before the base packages of Leap and SLE were completely aligned. From openSUSE Leap 15 and onwards, SUSE officially supported organizations who wanted to migrate from Leap 15 to SLE 15. And this new release takes that integration even further. From openSUSE Leap 15.3 and onwards, the binary packages of the base of Leap 15.3 and SLE 15 Service Pack 3 will be identical. The packages on top of that base will be ‘community backports’. And these packages will work on both Leap 15.3 and on SLE 15 Service Pack 3.
So you will get a rock solid distribution, because it needs to be enterprise grade. Enterprises don’t have the time, nor the willingness to mess with software. They want to get work done. The software should just work. And that is exactly what you should expect from openSUSE Leap 15.3. This might be a bit boring for a reviewer or for a Linux enthusiast. Because a typical Linux enthusiast wants to try out the latest and greatest software. They want to play around with the new KDE Plasma 5.22 (released on the 8th June 2021). Or they want to play with the new GNOME 40 desktop (released on the 24th March 2021). They can, if they install the latest openSUSE Tumbleweed.
openSUSE Leap 15.3 is based on the Linux 5.3.18 kernel, which was released on the 18th of December 2019. The GNOME desktop is version 3.34 (the same as Leap 15.2), which was released on the 12th of September 2019. And the KDE Plasma version is 5.18 LTS (the same as Leap 15.2), which was released on the 11th of February 2020. Only the XFCE desktop has seen an upgrade to version 4.16, which released on the 22nd of December 2020. You get the idea, the software is at least 6 months to well over 1 year old. Tried and tested software, so to speak. But what is new?
What is new in openSUSE Leap 15.3?
| Package name | Leap 15.2 | Leap 15.2 with updates |
Leap 15.3 with updates |
Tumbleweed (Jun 2021) |
| Audacity | 2.2.2 | 2.2.2 | 2.2.2 | 3.0.2 |
| Calibre | 3.48 | 3.48 | 3.48 | 5.21 |
| Chromium | 81 | 91 | 91 | 91 |
| Darktable | 2.6.3 | 2.6.3 | 3.4.1 | 3.4.1 |
| Digikam | 6.4 | 6.4 | 7.1 | 7.2 |
| Elisa | 20.04 | 20.04 | 20.04 | 21.04 |
| Flatpak | 1.6.3 | 1.10.2 | 1.10.2 | 1.11.1 |
| GIMP | 2.10.12 | 2.10.12 | 2.10.12 | 2.10.24 |
| GNOME Shell | 3.34 | 3.34 | 3.34 | 40.0 |
| GNOME Applications | 3.34 | 3.34 | 3.34 | 40.0 |
| GNU Cash | 3.9 | 3.9 | 3.9 | 4.5 |
| Hugin | 2019.2 | 2019.2 | 2019.2 | 2020.0 |
| Inkscape | 0.92.2 | 0.92.2 | 1.0.1 | 1.0.2 |
| Kdenlive | 19.12.3 | 20.04.2 | 20.04.2 | 21.04.1 |
| KDE Plasma 5 desktop | 5.18.4 | 5.18.6 | 5.18.6 | 5.22.0 |
| KDE Applications | 19.12.3 | 20.04.2 | 20.04.2 | 21.04.1 |
| Krita | 4.2.9 | 4.2.9 | 4.4.2 | 4.4.5 |
| LibreOffice | 6.4.2 | 7.1.3 | 7.1.2 | 7.1.3 |
| Linux kernel | 5.3.18 | 5.3.18 | 5.3.18 | 5.12.9 |
| Mozilla Firefox | 68.6 | 78.11 | 78.11 | 89.0 |
| Mozilla Thunderbird | 68.6 | 78.10 | 78.11 | 78.11 |
| OpenShot | 2.4.1 | 2.4.1 | 2.4.1 | 2.5.1 |
| Rapid Photo Downloader | 0.9.22 | 0.9.24 | 0.9.26 | 0.9.26 |
| Scribus | 1.5.5 | 1.5.5 | 1.5.6 | 1.5.7 |
| Telegram | 2.0.1 | 2.1.11 | 2.5.8 | 2.7.5 |
| VLC | 3.0.7 | 3.0.13 | 3.0.13 | 3.0.13 |
| YaST | 4.2.82 | 4.2.93 | 4.3.62 | 4.4.0 |
- In green, I highlighted the packages that are significantly changed in comparison to Leap 15.2.
- In blue, I highlighted the packages that are changed compared to Leap 15.2 at time of its release, but which are now also available in updated Leap 15.2 installations.
From the table, it becomes clear that some of the bigger productivity applications are kept up-to-date both in Leap 15.2 and Leap 15.3, such as: Darktable, Digikam, Inkscape, Krita, LibreOffice, Firefox ESR, Thunderbird and VLC. openSUSE can still do a better job if they kept GIMP up to date as well, but even GIMP is not too far behind. The point that I like to make is that if you just want to use your computer, openSUSE Leap 15.3 should suffice for that. Not everyone needs the transparent panel functionality that is offered in the KDE Plasma 5.22 desktop. And not everybody needs the new horizontal layout of GNOME 40, when the vertical layout has been refined a lot over the last 10 GNOME iterations. Sure those features are nice to have. But they won’t break the user experience when they are not included. Remember: only a year ago, everybody thought these experiences where the best thing since slided bread.
The upgrade experience
This time, I have decided to upgrade both my laptop (the HP Pavilion 14-ce0830nd) and my desktop (the HP Pavilion Power 580-146nd). The openSUSE installer did ask me to make some manual choices about package conflicts. That might be the result of me having ~10 additional repositories enabled. So my system is not really a stock installation. Without some technical knowledge, I think the questions on file conflicts are not easy to resolve for a new Linux user. This is also a problem during regular updates, so this is a broader openSUSE issue. The YaST installer just offers too much technical choices. Most of the time, there is only 1 valid option. Yes, please make the required changes; downgrade the package or change the repository. Of course I don’t want to keep a package with broken dependencies. And of course I don’t want to delete the application, which I want to keep using. If YaST just removed those choices, in most cases the user doesn’t have to make any manual changes. End of rant.
On the laptop, I had to make more manual choices and this seemed a more complex installation. After the installation, I had to re-install some packages (gnucash, hedgewars and wesnoth) that were not transferred correctly. And I have also removed all (openSUSE Leap 15.2) packages that were left without a repository. Most of these (library) packages had a more modern version in Leap 15.3, but because the version number is included in the package name (instead of in the version number) they were not removed.
On the desktop, I tried to directly upgrade the system with the proprietary Nvidia drivers, which didn’t work out. I did have a successful installation, but I could only use the command line. After running YaST from the command line and re-installing the Nvidia packages (nvidia-computeG05) and rebooting, my system showed the login screen and my problem was resolved. A lesson for the future: when upgrading, do not enable the Nvidia repository. Install these proprietary drivers after the upgrade. After the installation, I had to re-install the same packages (gnucash, hedgewars and wesnoth) that were not transferred correctly. But now that is all said and done, I am very happy that both my systems are running on the latest and greatest openSUSE Leap 15.3.

Published on: 13 June 2021
openSUSE Tumbleweed – Review of the week 2021/23
Dear Tumbleweed users and hackers,
Today, the weekly review reaches you a little bit late: I was out early yesterday to enjoy the weather. Here, the sun is finally coming out for more than just a few minutes. But, back to the important things that are the openSUSE Tumbleweed snapshots. Namely, we have released 6 snapshots (0603, 0604, 0605, 0606, 0609, and 0610) in the last week.
The major changes included:
- Linux kernel 5.12.9
- Mesa 21.1.2
- KDE Plasma 5.22.0
- libxml 2.9.12
- Apache 2.4.48
- PHP 7.4.20
- Chrony 4.1
- cURL 7.77.0
- Mozilla Thunderbird 78.11.0
- OpenSSH: move of the distro default config to /usr/etc. Admin config is supposed to be in /etc. Make sure to check the .rpmsave files after the update. Best to put config snippets in /etc/ssh/sshd_config.d/*.conf files to inherit distro config changes
The changes planned for the future snapshots include:
- python3x packages will no longer provide a python symbol. This caused some confusion in the past when people expected ‘python’ to be the legacy python2, but python3x provided it as well.
- Linux kernel 5.12.10
- GNOME 40.2
- systemd 248
- KDE Gear 21.04.2
- Cinnamon 5.0
I just checked my email and I got email from