Librsvg accepting interns for Summer of Code 2020
Are you a student qualified to run for Summer of Code 2020? I'm willing to mentor the following project for librsvg.
Project: Revamp the text engine in librsvg
Librsvg supports only a few features of the SVG Text specification. It requires extra features to be really useful:
-
Proper bidirectional support. Librsvg supports the
directionandunicode-bidiproperties for text elements, among others, but in a very rudimentary fashion. It just translates those properties to Pango terminology and asksPangoLayoutto lay out the text. SVG really wants finer control of that, for which... -
... ideally you would make librsvg use Harfbuzz directly, or a wrapper that is close to its level of operation. Pango is a bit too high level for the needs of SVG.
-
Manual layout of text glyphs. After a text engine like Harfbuzz does the shaping, librsvg would need to lay out the produced glyphs in the way of the SVG attributes
dx, dy, x, y, etc. The SVG Text specification has the algorithms for this. -
The cherry on top: text-on-a-path. Again, the spec has the details. You would make Wikimedia content creators very happy with this!
Requirements: Rust for programming language; some familiarity with Unicode concepts and text layout. Familiarity with Cairo and Harfbuzz would help a lot. Preference will be given to people who can write a right-to-left human language, or a language that requires complex shaping.
Maintain release info easily in MetaInfo/Appdata files
This article isn’t about anything “new”, like the previous ones on AppStream – it rather exists to shine the spotlight on a feature I feel is underutilized. From conversations it appears that the reason simply is that people don’t know that it exists, and of course that’s a pretty bad reason not to make your life easier 😉
Mini-Disclaimer: I’ll be talking about appstreamcli, part of AppStream, in this blogpost exclusively. The appstream-util tool from the appstream-glib project has a similar functionality – check out its help text and look for appdata-to-news if you are interested in using it instead.
What is this about?
AppStream permits software to add release information to their MetaInfo files to describe current and upcoming releases. This feature has the following advantages:
- Distribution-agnostic format for release descriptions
- Provides versioning information for bundling systems (Flatpak, AppImage, …)
- Release texts are short and end-user-centric, not technical as the ones provided by distributors usually are
- Release texts are fully translatable using the normal localization workflow for MetaInfo files
- Releases can link artifacts (built binaries, source code, …) and have additional machine-readable metadata e.g. one can tag a release as a development release
The disadvantage of all this, is that humans have to maintain the release information. Also, people need to write XML for this. Of course, once humans are involved with any technology, things get a lot more complicated. That doesn’t mean we can’t make things easier for people to use though.
Did you know that you don’t actually have to edit the XML in order to update your release information? To make creating and maintaining release information as easy as possible, the appstreamcli utility has a few helpers built in. And the best thing is that appstreamcli, being part of AppStream, is available pretty ubiquitously on Linux distributions.
Update release information from NEWS data
The NEWS file is a not very well defined textfile that lists “user-visible changes worth mentioning” per each version. This maps pretty well to what AppStream release information should contain, so let’s generate that from a NEWS file!
Since the news format is not defined, but we need to parse this somehow, the amount of things appstreamcli can parse is very limited. We support a format in this style:
Version 0.2.0
~~~~~~~~~~~~~~
Released: 2020-03-14
Notes:
* Important thing 1
* Important thing 2
Features:
* New/changed feature 1
* New/changed feature 2 (Author Name)
* ...
Bugfixes:
* Bugfix 1
* Bugfix 2
* ...
Version 0.1.0
~~~~~~~~~~~~~~
Released: 2020-01-10
Features:
* ...
When parsing a file like this, appstreamcli will allow a lot of errors/”imperfections” and account for quite a few style and string variations. You will need to check whether this format works for you. You can see it in use in appstream itself and libxmlb for a slightly different style.
So, how do you convert this? We first create our NEWS file, e.g. with this content:
Version 0.2.0
~~~~~~~~~~~~~~
Released: 2020-03-14
Bugfixes:
* The CPU no longer overheats when you hold down spacebar
Version 0.1.0
~~~~~~~~~~~~~~
Released: 2020-01-10
Features:
* Now plays a "zap" sound on every character input
For the MetaInfo file, we of course generate one using the MetaInfo Creator. Then we can run the following command to get a preview of the generated file: appstreamcli news-to-metainfo ./NEWS ./org.example.myapp.metainfo.xml - Note the single dash at the end – this is the explicit way of telling appstreamcli to print something to stdout. This is how the result looks like:
<?xml version="1.0" encoding="utf-8"?>
<component type="desktop-application">
[...]
<releases>
<release type="stable" version="0.2.0" date="2020-03-14T00:00:00Z">
<description>
<p>This release fixes the following bug:</p>
<ul>
<li>The CPU no longer overheats when you hold down spacebar</li>
</ul>
</description>
</release>
<release type="stable" version="0.1.0" date="2020-01-10T00:00:00Z">
<description>
<p>This release adds the following features:</p>
<ul>
<li>Now plays a "zap" sound on every character input</li>
</ul>
</description>
</release>
</releases>
</component>
Neat! If we want to save this to a file instead, we just exchange the dash with a filename. And maybe we don’t want to add all releases of the past decade to the final XML? No problem too, just pass the --limit flag as well: appstreamcli news-to-metainfo --limit=6 ./NEWS ./org.example.myapp.metainfo.tmpl.xml ./result/org.example.myapp.metainfo.xml
That’s nice on its own, but we really don’t want to do this by hand… The best way to ensure the MetaInfo file is updated, is to simply run this command at build time to generate the final MetaInfo file. For the Meson build system you can achieve this with a code snippet like below (but for CMake this shouldn’t be an issue either – you could even make a nice macro for it there):
ascli_exe = find_program('appstreamcli')
metainfo_with_relinfo = custom_target('gen-metainfo-rel',
input : ['./NEWS', 'org.example.myapp.metainfo.xml'],
output : ['org.example.myapp.metainfo.xml'],
command : [ascli_exe, 'news-to-metainfo', '--limit=6', '@INPUT0@', '@INPUT1@', '@OUTPUT@']
)
In order to also translate releases, you will need to add this to your .pot file generation workflow, so (x)gettext can run on the MetaInfo file with translations merged in.
Release information from YAML files
Since parsing a “no structure, somewhat human-readable file” is hard without baking an AI into appstreamcli, there is also a second option available: Generate the XML from a YAML file. YAML is easy to write for humans, but can also be parsed by machines.The YAML structure used here is specific to AppStream, but somewhat maps to the NEWS file contents as well as MetaInfo file data. That makes it more versatile, but in order to use it, you will need to opt into using YAML for writing news entries. If that’s okay for you to consider, read on!
A YAML release file has this structure:
---
Version: 0.2.0
Date: 2020-03-14
Type: development
Description:
- The CPU no longer overheats when you hold down spacebar
- Fixed bugs ABC and DEF
---
Version: 0.1.0
Date: 2020-01-10
Description: |-
This is our first release!
Now plays a "zap" sound on every character input
As you can see, the release date has to be an ISO 8601 string, just like it is assumed for NEWS files. Unlike in NEWS files, releases can be defined as either stable or development depending on whether they are a stable or development release, by specifying a Type field. If no Type field is present, stable is implicitly assumed. Each release has a description, which can either be a free-form multi-paragraph text, or a list of entries.
Converting the YAML example from above is as easy as using the exact same command that was used before for plain NEWS files: appstreamcli news-to-metainfo --limit=6 ./NEWS.yml ./org.example.myapp.metainfo.tmpl.xml ./result/org.example.myapp.metainfo.xml If appstreamcli fails to autodetect the format, you can help it by specifying it explicitly via the --format=yaml flag. This command would produce the following result:
<?xml version="1.0" encoding="utf-8"?>
<component type="console-application">
[...]
<releases>
<release type="development" version="0.2.0" date="2020-03-14T00:00:00Z">
<description>
<ul>
<li>The CPU no longer overheats when you hold down spacebar</li>
<li>Fixed bugs ABC and DEF</li>
</ul>
</description>
</release>
<release type="stable" version="0.1.0" date="2020-01-10T00:00:00Z">
<description>
<p>This is our first release!</p>
<p>Now plays a "zap" sound on every character input</p>
</description>
</release>
</releases>
</component>
Note that the 0.2.0 release is now marked as development release, a thing which was not possible in the plain text NEWS file before.
Going the other way
Maybe you like writing XML, or have some other tool that generates the MetaInfo XML, or you have received your release information from some other source and want to convert it into text. AppStream also has a tool for that! Using appstreamcli metainfo-to-news <metainfo-file> <news-file> you can convert a MetaInfo file that has release entries into a text representation. If you don’t want appstreamcli to autodetect the right format, you can specify it via the --format=<text|yaml> switch.
Future considerations
The release handling is still not something I am entirely happy with. For example, the release information has to be written and translated at release time of the application. For some projects, this workflow isn’t practical. That’s why issue #240 exists in AppStream which basically requests an option to have release notes split out to a separate, remote location (and also translations, but that’s unlikely to happen). Having remote release information is something that will highly likely happen in some way, but implementing this will be a quite disruptive, if not breaking change. That is why I am holding this change back for the AppStream 1.0 release.
In the meanwhile, besides improving the XML form of release information, I also hope to support a few more NEWS text styles if they can be autodetected. The format of the systemd project may be a good candidate. The YAML release-notes format variant will also receive a few enhancements, e.g. for specifying a release URL. For all of these things, I very much welcome pull requests or issue reports. I can implement and maintain the things I use myself best, so if I don’t use something or don’t know about a feature many people want I won’t suddenly implement it or start to add features at random because “they may be useful”. That would be a recipe for disaster. This is why for these features in particular contributions from people who are using them in their own projects or want their new usecase represented are very welcome.
Reducing memory consumption in librsvg, part 1: text nodes
Librsvg's memory consumption has not been a problem so far for GNOME's use cases, which is basically rendering icons. But for SVG files with thousands of elements, it could do a lot better.
Memory consumption in the DOM
Librsvg shares some common problems with web browsers: it must
construct a DOM tree in memory with SVG elements, and keep a bunch of
information for each of the tree's nodes. For example, each SVG
element may have an id attribute, or a class; each one has a
transformation matrix; etc.
Apart from the tree node metadata (pointers to sibling and parent nodes), each node has this:
/// Contents of a tree node
pub struct NodeData {
node_type: NodeType,
element_name: QualName,
id: Option<String>, // id attribute from XML element
class: Option<String>, // class attribute from XML element
specified_values: SpecifiedValues,
important_styles: HashSet<QualName>,
result: NodeResult,
transform: Transform,
values: ComputedValues,
cond: bool,
style_attr: String,
node_impl: Box<dyn NodeTrait>, // concrete struct for node types
}
On a 64-bit box, that NodeData struct is 1808 bytes. And the biggest fields
are the SpecifiedValues (824 bytes) and ComputedValues (704 bytes).
Librsvg represents all tree nodes with that struct. Consider an SVG like this:
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<rect x="10" y="20"/>
<path d="..."/>
<text x="10" y="20">Hello</text>
<!-- etc -->
</svg>
There are 4 elements in that file. However, there are also tree nodes
for the XML text nodes, that is, the whitespace between tags and the
"Hello" inside the <text> element.
The contents of each of those text nodes is tiny (a newline and maybe
a couple of spaces), but each node still takes up at least 1808 bytes
from the NodeData struct, plus the size of the text string.
Let's refactor this to make it easier to remove that overhead.
First step: separate text nodes from element nodes
Internally, librsvg represents XML text nodes with a NodeChars struct
which is basically a string with some extra stuff. All the concrete
structs for tree node types must implement a trait called NodeTrait,
and NodeChars is no exception:
pub struct NodeChars {
// a string with the text node's contents
}
impl NodeTrait for NodeChars {
// a mostly empty impl with methods that do nothing
}
You don't see it in the definition of NodeData in the previous
section, but for a text node, the NodeData.node_impl field would
point to a heap-allocated NodeChars (it can do that, since
NodeChars implements NodeTrait, so it can go into node_impl:
Box<dyn NodeTrait>).
First, I turned the NodeData struct into an enum with two variants,
and moved all of its previous fields to an Element struct:
// This one is new
pub enum NodeData {
Element(Element),
Text(NodeChars),
}
// This is the old struct with a different name
pub enum Element {
node_type: NodeType,
element_name: QualName,
id: Option<String>,
class: Option<String>,
specified_values: SpecifiedValues,
important_styles: HashSet<QualName>,
result: NodeResult,
transform: Transform,
values: ComputedValues,
cond: bool,
style_attr: String,
node_impl: Box<dyn NodeTrait>,
}
The size of a Rust enum is the maximum of the sizes of its variants, plus a little extra for the discriminant (you can think of a C struct with an int for the discriminant, and a union of variants).
The code needed a few
changes
to split NodeData in this way, by adding accessor
functions to each of the Element or Text cases conveniently. This
is one of those refactors where you can just change the declaration,
and walk down the compiler's errors to make each case use the accesors
instead of whatever was done before.
Second step: move the Element variant to a separate allocation
Now, we turn NodeData into
this:
pub enum NodeData {
Element(Box<Element>), // This goes inside a Box
Text(NodeChars),
}
That way, the Element variant is the size of a pointer (i.e. a
pointer to the heap-allocated Box), and the Text variant is as big
as NodeChars as usual.
This means that Element nodes are just as big as before, plus an
extra pointer, plus an extra heap allocation.
However, the Text nodes get a lot smaller!
- Before:
sizeof::<NodeData>() = 1808 - After:
sizeof::<NodeData>() = 72
By making the Element variant a lot smaller (the size of a Box,
which is just a pointer), it has no extra overhead on the Text
variant.
This means that in the SVG file, all the whitespace between XML elements now takes a lot less memory.
Some numbers from a pathological file
Issue 42 is about
an SVG file that is just a <use> element repeated many times, once
per line:
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<symbol id="glyph0-0">
<!-- a few elements here -->
</symbol>
</defs>
<use xlink:href="#glyph0-0" x="1" y="10"/>
<use xlink:href="#glyph0-0" x="1" y="10"/>
<use xlink:href="#glyph0-0" x="1" y="10"/>
<!-- about 196,000 similar lines -->
</svg>
So we have around 196,000 elements. According to Valgrind's Massif
tool, this makes rsvg-convert allocate 800,501,568 bytes in the
old version, versus 463,412,720 bytes in the new version, or about 60%
of the space.
Next steps
There is a lot of repetition in the text nodes of a typical SVG file. For example, in that pathological file above, most of the whitespace is identical: between each element there is a newline and two spaces. Instead of having thousands of little allocations, all with the same string, there could be a pool of shared strings. Files with "real" indentation could get benefits from sharing the whitespace-only text nodes.
Real browser engines are very careful to share the style structs across elements if possible. Look for "style struct sharing" in "Inside a super fast CSS engine: Quantum CSS". This is going to take some good work in librsvg, but we can get there gradually.
References
- Commits for the whole refactoring
- Turn the NodeData struct into an enum with variants for Element and Text
- Box the Element variant to make Text nodes smaller. The commit message has parts of the massif log with all the interesting numbers.
- Tracker bug for memory consumption
openSUSE.Asia Summit 2020 Announcement
Faridabad, India, Selected for openSUSE.Asia Summit 2020

India was accepted to host the openSUSE.Asia Summit 2020. openSUSE.Asia summit is going to be held for the first time in India, Faridabad.Faridabad is a district of Haryana situated in the National Capital Region bordering the Indian capital New Delhi.
The supporters of openSUSE in India, and of Free/Libre Open Source Software (FLOSS) at large are excited to organize
the most awaited openSUSE.Asia Summit event. In this activity, experts, contributors, end users, and technology enthusiasts
will gather to share experiences about the development of openSUSE and other things related to FLOSS and have a lot of fun.
The venue for the openSUSE.Asia Summit was chosen after being proposed by the Indian community during
openSUSE.Asia Summit 2019 in Bali, Indonesia. Finally, the
Asian committee decided Faridabad as the host of
openSUSE.Asia Summit 2020 from September 25 to September 27, 2020, at
Manav Rachna International Institute of Research & Studies, Faridabad.
Goals to be achieved in the openSUSE.Asia Summit 2020 in Faridabad include:
- To promote openSUSE in India.
- To attract new contributors for openSUSE from India and other Asian countries.
- To provide an alternative to the wider community that FLOSS can be a powerful tool for doing their daily job.
- To provide a platform for sharing user and developer experiences usually such discussions only occur online.
In the end, we are proud to present India as one of the best places for the openSUSE.Asia Summit.
Pre-announcement
openSUSE.Asia Summit 2020 will immediately open a call for paper for prospective speakers.
In addition, a logo competition for the openSUSE.Asia Summit 2020 will also be opened.
This would surely be an opportunity for designers in Asia to compete with each other to show their abilities and contribute
to this activity. More details about the above information will be informed in the near future through news.opensuse.org.
See you in India !!
DevCon 2020 | Kubernetes - Introducing through openSUSE MicroOS & Kubic
Guest post by Chittesh Sham 😉
DevCon 2020 is just about three weeks away and the hype is real.
People know me as a friendly neighborhood SysAdmin and this year I am excited to announce that I will be co-hosting a presentation alongside Ish at the Developers Conference. It has been a long time coming, and as you might have noticed Ish has been building up to this one, starting with his Kubic Presentation at DevCon 2019 , openSUSE MicroOS in Production talk at openSUSE Conference 2019 and a workshop on Managing Pods & Containers at the openSUSE Asia Summit.

We have been experimenting with a bunch of tools such as Podman, Buildah, Skopeo and openSUSE Kubic for a while now and we would like to share our experience.
Our presentation is scheduled on Saturday 4 April 2020, 2:30pm - 3:15pm in the Kryptone room at the Caudan Arts Centre. We will also be around for all three days at the conference, so if you want to grab a coffee and geek out on openSUSE and Kubernetes, don't hesitate to hit us up!
I would like to give express my gratitude to the Linux Foundation and Cloud Native Computing Foundation (CNCF) for their support. I was impressed by Chris Aniszczyk, especially how quickly he reacted to show his support upon noticing our talk.
It was incredible how fast the goodies from store.cncf.io (US) came to Mauritius. Kudos to FedEx for making that possible in just 5 days time! Here are some goodies that you can expect to be handed out during #DevConMU20



See you at DevCon Geeks! 🤓
Introducing the MetaInfo Creator
This year’s FOSDEM conference was a lot of fun – one of the things I always enjoy most about this particular conference (besides having some of the outstanding food you can get in Brussels and meeting with friends from the free software world) is the ability to meet a large range of new people who I wouldn’t usually have interacted with, or getting people from different communities together who otherwise would not meet in person as each bigger project has their own conference (for example, the amount of VideoLAN people is much lower at GUADEC and Akademy compared to FOSDEM). It’s also really neat to have GNOME and KDE developers within reach at the same place, as I care about both desktops a lot.
An unexpected issue
This blog post however is not about that. It’s about what I learned when talking to people there about AppStream, and the outcome of that. Especially when talking to application authors but also to people who deal with larger software repositories, it became apparent that many app authors don’t really want to deal with the extra effort of writing metadata at all. This was a bit of a surprise to me, as I thought that there would be a strong interest for application authors to make their apps look as good as possible in software catalogs.
A bit less surprising was the fact that people apparently don’t enjoy reading a large specification, reading a long-ish intro guide with lots of dos and don’ts or basically reading any longer text at all before being able to create an AppStream MetaInfo/AppData file describing their software.
Another common problem seems to be that people don’t immediately know what a “reverse-DNS ID” is, the format AppStream uses for uniquely identifying each software component. So naturally, people either have to read about it again (bah, reading!
) or make something up, which occasionally is wrong and not the actual component-ID their software component should have.
The MetaInfo Creator
It was actually suggested to me twice that what people really would like to have is a simple tool to put together a MetaInfo file for their software. Basically a simple form with a few questions which produces the final file. I always considered this a “nice to have, but not essential” feature, but now I was convinced that this actually has a priority attached to it.
So, instead of jumping into my favourite editor and writing a bunch of C code to create this “make MetaInfo file” form as part of appstreamcli, this time I decided to try what the cool kids are doing and make a web application that runs in your browser and creates all metadata there.
So, behold the MetaInfo Creator! If you click this link, you will end up at an Angular-based web application that will let you generate MetaInfo/AppData files for a few component-types simply by answering a set of questions.
The intent was to make this tool as easy to use as possible for someone who basically doesn’t know anything about AppStream at all. Therefore, the tool will:
- Generate a rDNS component-ID suggestion automatically based on the software’s homepage and name
- Fill out default values for anything it thinks it has enough data for
- Show short hints for what values we expect for certain fields
- Interactively validate the entered value, so people know immediately when they have entered something invalid
- Produce a .desktop file as well for GUI applications, if people select the option for it
- Show additional hints about how to do more with the metadata
- Create some Meson snippets as pointers how people can integrate the MetaInfo files into projects using the Meson build system
For the Meson feature, the tool simply can not generate a “use this and be done” script, as each Meson snippet needs to be adjusted for the individual project. So this option is disabled by default, but when enabled, a few simple Meson snippets will be produced which can be easily adjusted to the project they should be part of.
The tool currently does not generate any release information for a MetaInfo file at all, This may be added in future. The initial goal was to have people create any MetaInfo file in the first place, having projects also ship release details would be the icing on the cake.
I hope people find this project useful and use it to create better MetaInfo files, so distribution repositories and Flatpak repos look better in software centers. Also, since MetaInfo files can be used to create an “inventory” of software and to install missing stuff as-needed, having more of them will help to build smarter software managers, create smaller OS base installations and introspect what software bundles are made of easily.
I welcome contributions to the MetaInfo Creator! You can find its source code on GitHub. This is my first web application ever, the first time I wrote TypeScript and the first time I used Angular, so I’d bet a veteran developer more familiar with these tools will cringe at what I produced. So, scratch that itch and submit a PR!
Also, if you want to create a form for a new component type, please submit a patch as well.
C developer’s experience notes for Angular, TypeScript, NodeJS
This section is just to ramble a bit about random things I found interesting as a developer who mostly works with C/C++ and Python and stepped into the web-application developer’s world for the first time.
For a project like this, I would usually have gone with my default way of developing something for the web: Creating a Flask-based application in Python. I really love Python and Flask, but of course using them would have meant that all processing would have had to be done on the server. One the one hand I could have used libappstream that way to create the XML, format it and validate it, but on the other hand I would have had to host the Python app on my own server, find a place at Purism/Debian/GNOME/KDE or get it housed at Freedesktop somehow (which would have taken a while to arrange) – and I really wanted to have a permanent location for this application immediately. Additionally, I didn’t want people to send the details of new unpublished software to my server.
TypeScript
I must say that I really like TypeScript as a language compared to JavaScript. It is not really revolutionary (I looked into Dart and other ways to compile $stuff to JavaScript first), but it removes just enough JavaScript weirdness to be pleasant to use. At the same time, since TS is a superset of JS, JavaScript code is valid TypeScript code, so you can integrate with existing JS code easily. Picking TS up took me much less than an hour, and most of its features you learn organically when working on a project. The optional type-safety is a blessing and actually helped me a few times to find an issue. It being so close to JS is both a strength and weakness: On the one hand you have all the JS oddities in the language (implicit type conversion is really weird sometimes) and have to basically refrain from using them or count on the linter to spot them, but on the other hand you can immediately use the massive amount of JavaScript code available on the web.
Angular
The Angular web framework took a few hours to pick up – there are a lot of concepts to understand. But ultimately, it’s manageable and pretty nice to use. When working at the system level, a lot of complexity is in understanding how the CPU is processing data, managing memory and using the low-level APIs the operating system provides. With the web application stuff, a lot of the complexity for me was in learning about all the moving parts the system is comprised of, what their names are, what they are, and what works with which. And that is not a flat learning curve at all. As C developer, you need to know how the computer works to be efficient, as web developer you need to know a bunch of different tools really well to be productive.
One thing I am still a bit puzzled about is the amount of duplicated HTML templates my project has. I haven’t found a way to reuse template blocks in multiple components with Angular, like I would with Jinja2. The documentation suggests this feature does not exist, but maybe I simply can’t find it or there is a completely different way to achieve the same result.
NPM Ecosystem
The MetaInfo Creator application ultimately doesn’t do much. But according to GitHub, it has 985 (!!!) dependencies in NPM/NodeJS. And that is the bare minimum! I only added one dependency myself to it. I feel really uneasy about this, as I prefer the Python approach of having a rich standard library instead of billions of small modules scattered across the web. If there is a bug in one of the standard library functions, I can submit a patch to Python where some core developer is there to review it. In NodeJS, I imagine fixing some module is much harder.
That being said though, using npm is actually pretty nice – there is a module available for most things, and adding a new dependency is easy. NPM will also manage all the details of your dependency chain, GitHub will warn about security issues in modules you depend on, etc. So, from a usability perspective, there isn’t much to complain about (unlike with Python, where creating or using a module ends up as a “fight the system” event way too often and the question “which random file do I need to create now to achieve what I want?” always exists. Fortunately, Poetry made this a bit more pleasant for me recently).
So, tl;dr for this section: The web application development excursion was actually a lot of fun, and I may make more of those in future, now that I learned more about how to write web applications. Ultimately though, I enjoy the lower-level software development and backend development a bit more.
Summary
Check out the MetaInfo Creator and its source code, if you want to create MetaInfo files for a GUI application, console application, addon or service component quickly.
openSUSE Summit Dublin Canceled
The openSUSE Summit Dublin has been canceled due to the cancellation of some talks and the cancellation of the in-person SUSECON 2020 in Dublin.
Concerns over the developing situation of COVID-19 coronavirus lead to the decision to cancel the openSUSE Summit Dublin as the venue would have been shared with SUSECON and is no longer available for the summit.
Contact ddemaio (@) opensuse.org if you have any questions concerning the summit.
openSUSE Tumbleweed – Review of the week 2020/10
Dear Tumbleweed users and hackers,
Tumbleweed – full steam ahead! There have been 6 snapshots in the last week, some with quite some changes. The snapshots were 0227, 0228, 0229, 0301, 0303 and 0304.
The changes include:
- Zypper 1.14.34: beware! This version no longer supports abbreviated command line parameters (e.g
zypper install --no-ris no longer accepted, you need to spell--no-recommendsout) - GCC 10 is available and provides base libraries to the system
- KDE Plasma 5.18.2
- Linux kernel 5.5.6
- Many changes in various YaST modules
- gimp 2.10.18
The future will bring those changes, sooner or later:
- Python 3.8: The latest fixes should be there. IF nothing new shows up, this will ship next week
- binutils 2.34
- Qt 5.15.0 (currently betas being tested)
- Ruby 2.7 – possibly paired with the removal of Ruby 2.6
- GCC 10 as the default compiler
- Removal of Python 2
- GNU Make 4.3
- RPM: change of database format to ndb
Highlights of YaST Development Sprint 94
The Contents
After some time of silent work (our previous blog post was published a month ago), the YaST Team is back with some news about the latest development sprint and some Hack Week experiments. Those news include:
- Enabling YaST on the Windows Subsystem for Linux
- Usability improvements for the Online Search, the Partitioner and the Kdump module
- Better control of overridden
sysctlconfiguration values - Improvements in the default selections of the upcoming SLE 15 SP2 installer
- New features for zSeries mainframes like Secure Boot and I/O devices auto-configuration
- And, as a bonus, a couple of Hack Week projects related to YaST, Ruby and Crystal
So, as you can see, we have a little bit of everything in the menu, from WSL to mainframes, from new features to small usability improvements, from installation to system fine-tuning… So let’s dive into the details!
Improved compatibility with WSL
Have you ever heard about WSL, the Windows Subsystem for Linux? To be honest, before this sprint we haven’t payed much attention to it either. But as both openSUSE Leap and SUSE Linux Enterprise (SLE) are available to Windows users via WSL images and the 15.2 releases of both distributions are approaching, we decided it was time to dive into WSL to research how it works and how can YaST be useful there.
Setting up an (open)SUSE test system inside a WSL environment was a piece of cake thanks to the excellent documentation at the openSUSE Wiki.
Many components of YaST are useless in WSL because not everything can actually be configured from the Linux system itself and because systemd is not available (we are talking exclusively about WSL1 here). But YaST is still very useful for the initial setup of the system when running the (open)SUSE image for the first time. It can be used to setup the first user, to confirm the license and, in the SLE case, also to register the system. The YaST modules for software management can also be very handy to customize the image at any point after that initial setup.
So far, we have done three changes to improve the experience of executing YaST within WSL.
- We increased the speed of the initial boot by removing calls to systemd when it is not available.
- We fixed the registration process for YaST Firstboot.
- We implemented a feature to explicitly mark YaST modules that work in WSL and show only those modules in the YaST control center.
We also documented all our findings about WSL in this document.
As always, we are hungry for feedback. Please reach out to us and tell us what’s your experience using YaST inside WSL and which modules do you miss the most.
Improving the UX of the Online Search
As we announced one month ago, YaST will offer a mechanism to
search for packages through all SUSE Linux Enterprise modules, even if
they are not registered. This feature, known as package online search,
was already available using zypper’s search-packages command or
through the SCC web interface.
After gathering some feedback during the sprint review meeting, we decided to invest some time improving the overall UX experience. Perhaps the most relevant change is the new summary screen, which shows the list of modules to activate and packages to install.
Additionally, we improved error handling and, by the way, we fixed the case sensitive filter.
…And the Partitioner as Well
The online search is not the only part of YaST that has received some love in the UX area. We also tried to improve a bit the usability of the Partitioner. In this occasion, based on the feedback coming from our users via openSUSE’s Bugzilla.
On one hand, we got a report about this dialog been too long to properly fit in low screen resolutions.
The result was even worse in a text console with a resolution of 80 columns and 24 lines, which is the minimum size we design all YaST screens to work on.
So we dropped some obsolete options and made others more compact. Now the dialog fits in 24 lines again.
And, as you can see below, it looks also nicer (or at least less overwhelming) in graphical mode as well. It’s worth mentioning we also took the opportunity to fix other related dialogs that had similar problems.
On the other hand, we also got a report about how inconvenient was to always jump to the first tab when a device was selected in the devices tree at the left of the Partitioner, forcing the user to click in the “Partitions” tab (or any other desired one) over and over.
In that regard and as you may remember, a couple of sprints ago we made the overview screen actionable, avoiding the navigation to the device page just to perform a simple action over it. But navigating through the different devices back and forth is still possible and useful. Now such navigation has been improved by remembering the last tab and row selected per section or device whenever possible, which will save you a bunch of clicks when working with multiple devices.
Related to this, we started a public discussion about what should be the default tab the first time a device is visited. Once again, we are looking for opinions. So we would be grateful if you read the thread and contribute to the discussion.
Showing Suggested Values for Kdump Configuration
But the Partitioner was not the only YaST module for which our users pointed usability problems via Bugzilla. After some changes in how Kdump works after the migration from openSUSE Leap 42.3 to 15.0, it turned out that using YaST to re-adjust the values was not as helpful as it should be. YaST Kdump displayed the current size of the memory reservations, as well as the min and max margins. But it did not show the recommended default values for the current system, so if the user has adjusted the limits in the past it was impossible to get an up-to-date proposal from YaST calculated for the current system.
We have adapted the dialog to show those suggested values. As you can see below, we also took the opportunity to extend the help text to explain the meaning of the different values.
Better Control of Overridden Kernel Parameter Values
And talking about YaST pieces we are improving step by step, you may
remember from our report of sprint 86 that we are adapting YaST to
deal with the new structure of the sysctl configuration.
Up to now YaST has stored sysctl values mainly in /etc/sysctl.conf
and /etc/sysctl.d/70-yast.conf. But this reflects only a part of the
possibilities for storing those values. The truth is that there are many
more locations where these settings can be stored: /run/sysctl.d,
/etc/sysctl.d, /usr/local/lib/sysctl.d, /usr/lib/sysctl.d,
/lib/sysctl.d, /etc/sysctl.conf…
Now YaST also takes care of these locations and informs the user if there are some conflicting values, as you can see in the following screenshot.
The Default Pre-selected SLE Modules
We have also invested some time smoothing some rough edges off the installation process for the upcoming openSUSE 15.2 and SLE 15 SP2. For example, if you register your SLE 15 product during installation you will see the available modules and extensions in the following dialog. Some of them are by default pre-selected because they either contain the base system components (kernel, glibc,…) or the product specific packages (e.g. GNOME for SLE Desktop).
However, if you skip the registration and use the packages from the DVD medium there were no modules or extension pre-selected. The problem is that the information about the default modules was only available in the SCC data which obviously is not available in an offline installation.
In SLE 15 SP2 we added this extra information to the installer configuration files so now also in an offline installation YaST can preselect the default modules for each product.
Proposing NTP Servers During Installation
And talking about offering sensible defaults for installation, we also
improved the situation regarding the configuration of the NTP server.
For openSUSE based systems (including Kubic) and a few SUSE products,
like CaaSP or SLE High Performance Computing, YaST sets up the NTP
daemon during installation. YaST tries to determine which server to use
through the DHCP information but, when it is not available, it will
propose one from openSUSE and SUSE pools (e.g.,
n.opensuse.pool.ntp.org where n is a number between 0 and 3).
However, we still were using the novell.pool.ntp.org pool for SUSE
based products. During this sprint, we have switched to the
suse.pool.ntp.org pool of servers and, additionally, we have
refactored some code in order to reduce duplication and improve
testability.
Secure Boot Support for IBM zSeries
You may have noticed by the recent sprint reports that we are improving several aspects related to the installation and configuration of zSeries mainframes. This sprint was not an exception… and will certainly not be the last one in that regard.
As a result of that effort, YaST now supports the Secure Boot feature found on the latest zSeries machines. It’s rather similar to the existing UEFI Secure Boot so we took the opportunity to unify the Secure Boot handling found on different architectures.
This means you get this checkbox if your zSeries machine does have Secure Boot support.
In addition, we added a shortcut link on the installation summary screen that lets you enable Secure Boot with just a click.
As mentioned, we took the opportunity to unify the management of Secure Boot in all platforms, so this new shortcut link is also available in x86_64 or aarch64 machines that have UEFI Secure Boot.
Automatic Configuration of I/O Devices in zSeries
And talking about zSeries mainframes, anyone having used Linux in one of those systems know that input/output devices, like disks or network cards, must be configured and activated before they can be detected and used normally by the operating system.
But thanks to the new I/O device auto-configuration mechanism, users can now specify IDs and settings of I/O devices that should be automatically enabled in Linux. We modified the installer to detect such configuration and trigger the corresponding configuration actions, removing the need of manually activating disks and network devices during the installation process.
This is still an experimental feature and we are waiting for feedback to make sure the current implementation works in all the desired scenarios. If everything goes as expected, the feature will debut in SLE 15 SP2.
Hack Week
As said at the beginning of the post, the main reason for spending almost a month without publishing any report was that the whole YaST Team at SUSE was diving into completely different topics due to Hack Week 19, which theme was “Simplify, Modernize and Accelerate”.
There were not many projects related to YaST in this edition of Hack Week, but there are at least two that could be interesting for YaST fans and contributors. Fortunately, we have published reports for both of them in the yast-devel mailing list. So check out the results of “Learn Crystal by Porting Part of YaST to that Language” and “YaST Logs Analyzer“.
More to come
Now that we are back to our usual development pace, we should have more news about YaST development in a couple of weeks. The plan is to focus on fixing bugs for the upcoming releases of openSUSE Leap and SUSE Enterprise Linux, but we are pretty sure we will still find interesting bits of information for you.
Meanwhile, keep in touch through the usual channels and have a lot of fun!
CLI Tools
I am quite happy with my zsh and its various plugins (git, kubernetes, docker, etc). Since in $DAYJOB I work with kubernetes a lot, I heavily use kubectl, kubectx, kubens etc. in combination with grep, jq, pipes, etc. and prefer these CLI tools always over clicking buttons or scrolling long pages in browser.
All these got me into thinking, if I were to write a command line application today (March 2020), which language / frameworks should I use ? Some self-imposed constraints:
- The CLI application will be short-lived and will be invoked multiple times everyday by developers/users (such as grep, ls, cat, sed, etc.) and not daemons or long running processes. It won't matter if they leak memory too ;-)
- It needs to be fast. Lightning speed.
- The tool development may also be split into two parts, a library and a binary, if it could help in developing parallel client implementations (may be in future a GUI tool)
- The tool is going to be a FOSS tool and would need some community presence in future.
- Tool needs to be cross platform (Mac, Linux, Windows)
This post is a summary of various candidates and their current strengths and weaknesses in my perspective.
C
+ Probably the language that will guarantee the fastest tool.+ Easy to write wrapper libraries/bindings for any language
+ There are libraries like glib which might help with achieving better platform portability than the default language.
- Manual memory management, crash prone
- Most young programmers of today may not bother contributing, even if they use. Heck, most do not even learn this language in most colleges anymore.
- If the tool has to work with network services, JSON etc., library support is not going to be easily available.
- i18n, Unicode support etc. may not be great out of the box
Note: C++ is just a more complicated and painful C in my personal experience. Even though I have heard nice things about SmartPointers etc., I am not really convinced that learning C++ is going to be beneficial in the long run and never really bothered to master it, after learning it at college. This is an intentional miss.
Java
+ Rich and mature libraries and ecosystem+ Complete platform independence and is guaranteed to run on Linux, Macs or Windows alike. Datatypes, Files etc. behave properly everywhere.
- Perception of slowness. There may be some JVM tweaking etc. needed and that is an extra effort. IIUC this would be a non-issue for long running processes.
- Unclear licensing: may require to pay money to Oracle
Special mention: Kotlin is a humongously better language than the Java 8 (with lambdas) that I recently used. It has been mentioned that future releases of Java would incorporate sexy aspects of Kotlin. Related talk. (Ignore the clickbait title, excellent talk really, strongly recommended).
Python
+ Good library support and hopefully all will migrate to Python 3- Not a fan of the language for various reasons. Whitespace for scope identification, Lack of static typing out of the box, type unsafety for variables, etc.
Javascript (With Typescript/Electron, etc)
+ The language with the most number of developers in today's scenario (biased as per my sample set)+ Excellent support for multiple natural languages, glyphs, diacritics, etc. Mature frameworks, processes for i18n, l10n, etc.
- Slow and hungry for memory/cpu
- Using nodejs for CLI applications though not unheard of, is not popular either (compared to the adoption of GUI applications via Electron)
D / Haskell / Rust / C#
These languages may be great but these are niche and are not widely used by a large number of programmers in my circle.Rust although is claimed to be gaining momentum for a long time now, I cannot recollect any popular application that I use everyday done with Rust. I have stopped using Firefox (in favor of Brave) and so not really sure what the current performance status of Rust is. I will however, keep a watch on Rust and would try to learn at some point of time, in near future.
Golang
+ Almost every new CLI tool that I have used fresh in the last 5 years or so, is done in Golang (docker, kube*, hugo, helm, etc)+ Excellent libraries: Cobra and Viper (Thanks to spf13)
+ Super simple to distribute. Static binaries.
+ Automatic memory management and highly performant.
+ Strong community presence
- Lack of generics is a pain. It is not a problem when developing HTTP servers, REST services etc. but definitely irritates when writing libraries
- Platform independence may be questionable. If the CLI tool is for something mission critical (a large number of users, lives depend on it, etc.), some of the discrepancies mentioned here may be dangerous.
Conclusion
I will choose Golang if it is for dayjob. I would however choose Kotlin if the development is for a hobby/pet project to learn.What will you choose, What merits/demerits do you see for these (or other) languages ? Also what libraries/frameworks will you choose for your language(s) of choice ?









