Posted on Leave a comment

Storage management with Cockpit

Cockpit is a very useful utility allowing you to manage a compatible system over the network from the comfort of a web browser (See the list of supported web browsers and Linux distributions). One such feature is the ability to manage storage configuration. Cockpit contains a frontend for udisks2 – it allows you to create new partitions or format, resize, mount, unmount or delete existing partitions without the need to do it manually from a terminal.

Note: please exercise caution when managing your system disk and it’s partitions – incorrectly handling them may leave your system in unbootable state or incur data loss.

Installing Cockpit

If you don’t have Cockpit installed yet you can do so by issuing:

sudo dnf install cockpit

Note: Depending on your install profile, Cockpit might already be installed and you can skip the installation step! Also, some users may need to install cockpit-storaged package along with it’s dependencies if it has not been installed:

sudo dnf install cockpit-storaged

Add the service to the firewall:

sudo firewall-cmd –add-service=cockpit –permanent

Afterwards enable and start the service:

sudo systemctl enable cockpit.socket –now

And after this everything should be ready and cockpit should be accessible by entering the computers IP address or network domain name in the browser followed by the port 9090. For example: https://cockpit-example.localdomain:9090

Note: you will need to authenticate as privileged user to be able to modify your storage configuration, so tick the “Reuse my password for privileged tasks” checkbox on the Cockpit login page.

Basic provisioning of the storage device

Visiting the “Storage” section will display various statistics and information about the state of the system storage. You can find information about the partitions, their respective mountpoints, realtime disk read/write stats and storage related log information. Also, you can format and partition any newly attached internal/external storage device or attach an NFS mount.

To format and partition a blank storage device, select the device under “Devices” section by clicking on it. This will bring you to the screen of the selected storage device. Here you’ll be able to create a new partition table or format and create new partitions. if the device is empty Cockpit will describe the content of the storage device as unknown.

Click on “Create New Partition Table” to prepare the device.
After the partition table has been created, create one or more partitions by clicking “Create Partition” – here you’ll be able to specify the size, name, mountpoint and mount options.

When partitioning the storage device you have the choice between “Don’t owerwrite exiting data” and “Overwrite existing data with zeroes” – this will take slightly longer but is useful if you want to confidently erase the content of the storage device. Please note that this may not be enough for a substitute if your organisation has regulations in place how securely storage data must be erased. If needed, you can also specify custom mount options if defaults don’t suit your needs.

To simply create a single partition taking up all the storage space on the device just specify the name, for example, use “test” then specify it’s mountpoint, such as “/mnt/test” and click “Ok”. If you don’t want it to be immediately mounted uncheck the “Mount Now” checkbox. Specifying the name is optional, but will help you to identify the partition when inspecting the mountpoints. This will create a new XFS (the default recommended filesystem format) formatted partition “test” and mount it to “/mnt/test”.

Here’s an example how that would look like :

$ df -h
Filesystem Size Used Avail Use% Mounted on /dev/mapper/fedora-root 15G 2.3G 13G 16% / /dev/vda2 1014M 185M 830M 19% /boot /dev/vda1 599M 8.3M 591M 2% /boot/efi /dev/vdb1 20G 175M 20G 1% /mnt/test

It will also add the necessary entry to your /etc/fstab so that the partition gets mounted at boot.

Logical Volume Management

Cockpit also offers users to easily create and manage LVM and RAID storage devices. To create new Logical Volume Group, click on the burger menu button in the devices section and select the “Create Volume Group”. Select the available storage device (only devices with unmounted or no partitions will show up) to finish the process and afterwards return to the storage section and select the newly created volume group. From here on you’ll be able to create individual logical volumes by clicking “Create new Logical Volume”. Similarly to individual partitions, you can specify the size of the logical volume during creation if you don’t want to use all the available space of the volume group. After creating the logical volumes you’ll still need to format them and specify mountpoints. This can be done just like creating individual partitions was described earlier only instead of specifying individual disk devices you’re selecting logical volumes.

Here’s how a Logical Volume Group named “vgroup” with two Logical Volumes (lvol0 and lvol1) named “test” mounted on /mnt/test and named “data” mounted on /mnt/data would look like:

$ df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/fedora-root 15G 2.3G 13G 16% / /dev/vda2 1014M 185M 830M 19% /boot /dev/vda1 599M 8.3M 591M 2% /boot/efi /dev/mapper/vgroup0-lvol0 10G 104M 9.9G 2% /mnt/test /dev/mapper/vgroup0-lvol1 10G 104M 9.9G 2% /mnt/data

Just like before – all the necessary information has been added to the configuration and should persist between system reboots.

Other storage related Cockpit features

Apart from the described features above Cockpit also allows you to mount iscsi disks and nfs mounts located on the network. However, these resources are usually hosted on a dedicated server and require additional configuration going beyond this article. At this time Cockpit itself doesn’t offer the ability for users to configure and serve iscsi and nfs mounts but this may subject to change as Cockpit is an open source project under active development.

Posted on Leave a comment

Control the firewall at the command line

A network firewall is more or less what it sounds like: a protective barrier that prevents unwanted network transmissions. They are most frequently used to prevent outsiders from contacting or using network services on a system. For instance, if you’re running a laptop at school or in a coffee shop, you probably don’t want strangers poking around on it.

Every Fedora system has a firewall built in. It’s part of the network functions in the Linux kernel inside. This article shows you how to change its settings using firewall-cmd.

Network basics

This article can’t teach you everything about computer networks. But a few basics suffice to get you started.

Any computer on a network has an IP address. Think of this just like a mailing address that allows correct routing of data. Each computer also has a set of ports, numbered 0-65535. These are not physical ports; instead, you can think of them as a set of connection points at the address.

In many cases, the port is a standard number or range depending on the application expected to answer. For instance, a web server typically reserves port 80 for non-secure HTTP communications, and/or 443 for secure HTTPS. The port numbers under 1024 are reserved for system and well-known purposes, ports 1024-49151 are registered, and ports 49152 and above are usually ephemeral (used only for a short time).

Each of the two most common protocols for Internet data transfer, TCP and UDP, have this set of ports. TCP is used when it’s important that all data be received and, if it arrives out of order, reassembled in the right order. UDP is used for more time-sensitive services that can withstand losing some data.

An application running on the system, such as a web server, reserves one or more ports (as seen above, 80 and 443 for example). Then during network communication, a host establishes a connection between a source address and port, and the destination address and port.

A network firewall can block or permit transmissions of network data based on rules like address, port, or other criteria. The firewall-cmd utility lets you interact with the rule set to view or change how the firewall works.

Firewall zones

To verify the firewall is running, use this command with sudo. (In fairness, you can run firewall-cmd without the sudo command in environments where PolicyKit is running.)

$ sudo firewall-cmd --state
running

The firewalld service supports any number of zones. Each zone can have its own settings and rules for protection. In addition, each network interface can be placed in any zone individually The default zone for an external facing interface (like the wifi or wired network card) on a Fedora Workstation is the FedoraWorkstation zone.

To see what zones are active, use the –get-active-zones flag. On this system, there are two network interfaces, a wired Ethernet card wlp2s0 and a virtualization (libvirt) bridge interface virbr0:

$ sudo firewall-cmd --get-active-zones
FedoraWorkstation interfaces: wlp2s0
libvirt interfaces: virbr0

To see the default zone, or all the defined zones:

$ sudo firewall-cmd --get-default-zone
FedoraWorkstation
$ sudo firewall-cmd --get-zones
FedoraServer FedoraWorkstation block dmz drop external home internal libvirt public trusted work

To see the services the firewall is allowing other systems to access in the default zone, use the –list-services flag. Here is an example from a customized system; you may see something different.

$ sudo firewall-cmd --list-services
dhcpv6-client mdns samba-client ssh

This system has four services exposed. Each of these has a well-known port number. The firewall recognizes them by name. For instance, the ssh service is associated with port 22.

To see other port settings for the firewall in the current zone, use the –list-ports flag. By the way, you can always declare the zone you want to check:

$ sudo firewall-cmd --list-ports --zone=FedoraWorkstation
1025-65535/udp 1025-65535/tcp

This shows that ports 1025 and above (both UDP and TCP) are open by default.

Changing zones, ports, and services

The above setting is a design decision.* It ensures novice users can use network facing applications they install. If you know what you’re doing and want a more protective default, you can move the interface to the FedoraServer zone, which prohibits any ports not explicitly allowed. (Warning: if you’re using the host via the network, you may break your connection — meaning you’ll have to go to that box physically to make further changes!)

$ sudo firewall-cmd --change-interface=<ifname> --zone=FedoraServer
success

* This article is not the place to discuss that decision, which went through many rounds of review and debate in the Fedora community. You are welcome to change settings as needed.

If you want to open a well-known port that belongs to a service, you can add that service to the default zone (or use –zone to adjust a different zone). You can add more than one at once. This example opens up the well-known ports for your web server for both HTTP and HTTPS traffic, on ports 80 and 443:

$ sudo firewall-cmd --add-service=http --add-service=https
success

Not all services are defined, but many are. To see the whole list, use the –get-services flag.

If you want to add specific ports, you can do that by number and protocol as well. (You can also combine –add-service and –add-port flags, as many as necessary.) This example opens up the UDP service for a network boot service:

$ sudo firewall-cmd --add-port=67/udp
success

Important: If you want your changes to be effective after you reboot your system or restart the firewalld service, you must add the –permanent flag to your commands. The examples here only change the firewall until one of those events next happens.

These are just some of the many functions of the firewall-cmd utility and the firewalld service. There is much more information on firewalld at the project’s home page that’s worth reading and trying out.


Photo by Jakob Braun on Unsplash.

Posted on Leave a comment

Announcing the release of Fedora 32 Beta

The Fedora Project is pleased to announce the immediate availability of Fedora 32 Beta, the next step towards our planned Fedora 32 release at the end of April.

Download the prerelease from our Get Fedora site:

Or, check out one of our popular variants, including KDE Plasma, Xfce, and other desktop environments, as well as images for ARM devices like the Raspberry Pi 2 and 3:

Beta Release Highlights

Fedora Workstation

New in Fedora 32 Workstation Beta is EarlyOOM enabled by default. EarlyOOM enables users to more quickly recover and regain control over their system in low-memory situations with heavy swap usage. Fedora 32 Workstation Beta also enables the fs.trim timer by default, which improves performance and wear leveling for solid state drives.

Fedora 32 Workstation Beta includes GNOME 3.36, the newest release of the GNOME desktop environment. It is full of performance enhancements and improvements. GNOME 3.36 adds a Do Not Disturb button in the notifications, improved setup for parental controls and virtualization, and tweaks to Settings. For a full list of GNOME 3.36 highlights, see the release notes.

Other updates

Fedora 32 Beta includes updated versions of many popular packages like Ruby, Python, and Perl. It also includes version 10 of the popular GNU Compiler Collection (GCC). We also have the customary updates to underlying infrastructure software, like the GNU C Library. For a full list, see the Change set on the Fedora Wiki.

Testing needed

Since this is a Beta release, we expect that you may encounter bugs or missing features. To report issues encountered during testing, contact the Fedora QA team via the mailing list or in the #fedora-qa channel on IRC Freenode. As testing progresses, common issues are tracked on the Common F32 Bugs page.

For tips on reporting a bug effectively, read how to file a bug.

What is the Beta Release?

A Beta release is code-complete and bears a very strong resemblance to the final release. If you take the time to download and try out the Beta, you can check and make sure the things that are important to you are working. Every bug you find and report doesn’t just help you, it improves the experience of millions of Fedora users worldwide! Together, we can make Fedora rock-solid. We have a culture of coordinating new features and pushing fixes upstream as much as we can. Your feedback improves not only Fedora, but Linux and free software as a whole.

More information

For more detailed information about what’s new on Fedora 32 Beta release, you can consult the Fedora 32 Change set. It contains more technical information about the new packages and improvements shipped with this release.


Photo by Josh Calabrese on Unsplash.

Posted on Leave a comment

Fedora community and the COVID-19 crisis

[This message comes directly from the desk of Matthew Miller, the Fedora Project Leader.  — Ed.] 

Congratulations to the Fedora community for the upcoming on-time release of Fedora 32 Beta. While we’ve gotten better at hitting our schedule over the years, it’s always nice to celebrate  a little bit each time we do. But that may not be what’s on your mind this week. Like you, I’ve been thinking a lot about the global COVID-19 pandemic. During the Beta period, many of us were unaffected by this outbreak, but as the effects intensify around the world, the month between now and the final release will be different.

“Friends” is the first of our Four Foundations for a reason: Fedora is a community. The most important Fedora concerns right now are your health and safety. Many of you are asked to work from home, to practice social distancing, or even to remain under quarantine. For some of you, this will mean more time to contribute to your favorite open source projects. For others, you have additional stress as partners, kids, and others in your life require additional care. For all of us, the uncertainty weighs on our minds.

I want to make one thing very clear: do not feel bad if you cannot contribute to the level you want to. We always appreciate what you do for the Fedora community, but your health — both physical and mental — is more important than shipping a release. As of right now, we’re planning to continue on schedule, but we understand that the situation is changing rapidly. We’re working on contingency plans and the option of delaying the Fedora 32 release remains on the table.

As you may already know, the Fedora Council has decided to refrain from sponsoring events through the end of the May. We will continue to re-evaluate this as the global situation changes. Please follow the directions of your local public health authorities and keep yourself safe.

Posted on Leave a comment

Connect your Google Drive to Fedora Workstation

There are plenty of cloud services available where you can store important documents. Google Drive is undoubtedly one of the most popular. It offers a matching set of applications like Docs, Sheets, and Slides to create content. But you can also store arbitrary content in your Google Drive. This article shows you how to connect it to your Fedora Workstation.

Adding an account

Fedora Workstation lets you add an account either after installation during first startup, or at any time afterward. To add your account during first startup, follow the prompts. Among them is a choice of accounts you can add:

Online account listing

Select Google and a login prompt appears for you to login, so use your Google account information.

Online account login dialog

Be aware this information is only transmitted to Google, not to the GNOME project. The next screen asks you to grant access, which is required so your system’s desktop can interact with Google. Scroll down to review the access requests, and choose Allow to proceed.

You can expect to receive notifications on mobile devices and Gmail that a new device — your system — accessed your Google account. This is normal and expected.

Online account access request dialog

If you didn’t do this at first startup, or you need to re-add your account, open the Settings tool, and select Online Accounts to add the account. The Settings tool is available through the dropdown at right side of the Top Bar (the “gear” icon), or by opening the Overview and typing settings. Then proceed as described above.

Using the Files app with Google Drive

Open the Files app (formerly known as nautilus). Locations the Files app can access appear on the left side. Locate your Google account in the list.

When you select this account, the Files app shows the contents of your Google drive. Some files can be opened using your Fedora Workstation local apps, such as sound files or LibreOffice-compatible files (including Microsoft Office docs). Other files, such as Google app files like Docs, Sheets, and Slides, open using your web browser and the corresponding app.

Remember that if the file is large, it will take some time to receive over the network so you can open it.

You can also copy and paste files in your Google Drive storage from or to other storage connected to your Fedora Workstation. You can also use the built in functions to rename files, create folders, and organize them.

Be aware that the Files app does not refresh contents in real time. If you add or remove files from other Google connected devices like your mobile phone or tablet, you may need to hit Ctrl+R to refresh the Files app view.


Photo by Beatriz Pérez Moya on Unsplash.

Posted on Leave a comment

Submit a supplemental wallpaper for Fedora 32

Attention Fedora community members: Fedora is seeking submissions for supplemental wallpapers to be included with the Fedora 32 release. Whether you’re an active contributor, or have been looking for a easy way to get started contributing, submitting a wallpaper is a great way to help. Read on for more details.

Each release, the Fedora Design Team works with the community on a set of 16 additional wallpapers. Users can install and use these to supplement the standard wallpaper.

Dates and deadlines

The submission phase opened as of March 7, 2020 and ends March 21, 2020 at 23:59 UTC.

Important note: In some circumstances, submissions during the final hours may not get into the election, if there is insufficient time to do legal research. Please help by following the guidelines correctly, and submit only work under a correct license.

The voting phase will open the Monday following the close of submissions, March 23, 2020, and will be open until the end of the month on March 31, 2020 at 23:59 UTC.

How to contribute a wallpaper

Fedora uses the Nuancier application to manage the submissions and the voting process. To submit, you need a Fedora account. If you don’t have one, create one here in the Fedora Account System (FAS). To vote you must have a signed contributor agreement (also accessible in FAS) which only takes a few moments.

You can access Nuancier here along with detailed instructions for submissions.

Posted on Leave a comment

Using the Quarkus Framework on Fedora Silverblue – Just a Quick Look

Quarkus is a framework for Java development that is described on their web site as:

A Kubernetes Native Java stack tailored for OpenJDK HotSpot and GraalVM, crafted from the best of breed Java libraries and standards

https://quarkus.io/ – Feb. 5, 2020

Silverblue — a Fedora Workstation variant with a container based workflow central to its functionality — should be an ideal host system for the Quarkus framework.

There are currently two ways to use Quarkus with Silverblue. It can be run in a pet container such as Toolbox/Coretoolbox. Or it can be run directly in a terminal emulator. This article will focus on the latter method.

Why Quarkus

According to Quarkus.io: “Quarkus has been designed around a containers first philosophy. What this means in real terms is that Quarkus is optimized for low memory usage and fast startup times.” To achieve this, they employ first class support for Graal/Substrate VM, build time Metadata processing, reduction in reflection usage, and native image preboot. For details about why this matters, read Container First at Quarkus.

Prerequisites

A few prerequisites will need to configured before you can start using Quarkus. First, you need an IDE of your choice. Any of the popular ones will do. VIM or Emacs will work as well. The Quarkus site provides full details on how to set up the three major Java IDE’s (Eclipse, Intellij Idea, and Apache Netbeans). You will need a version of JDK installed. JDK 8, JDK 11 or any distribution of OpenJDK is fine. GrallVM 19.2.1 or 19.3.1 is needed for compiling down to native. You will also need Apache Maven 3.53+ or Gradle. This article will use Maven because that is what the author is more familiar with. Use the following command to layer Java 11 OpenJDK and Maven onto Silverblue:

$ rpm-ostree install java-11-openjdk* maven

Alternatively, you can download your favorite version of Java and install it directly in your home directory.

After rebooting, configure your JAVA_HOME and PATH environment variables to reference the new applications. Next, go to the GraalVM download page, and get GraalVM version 19.2.1 or version 19.3.1 for Java 11 OpenJDK. Install Graal as per the instructions provided. Basically, copy and decompress the archive into a directory under your home directory, then modify the PATH environment variable to include Graal. You use it as you would any JDK. So you can set it up as a platform in the IDE of your choice. Now is the time to setup the native image if you are going to use one. For more details on setting up your system to use Quarkus and the Quarkus native image, check out their Getting Started tutorial. With these parts installed and the environment setup, you can now try out Quarkus.

Bootstrapping

Quarkus recommends you create a project using the bootstrapping method. Below are some example commands entered into a terminal emulator in the Gnome shell on Silverblue.

$ mvn io.quarkus:quarkus-maven-plugin:1.2.1.Final:create \ -DprojectGroupId=org.jakfrost \ -DprojectArtifactId=silverblue-logo \ -DclassName="org.jakfrost.quickstart.GreetingResource" \ -Dpath="/hello"
$ cd silverblue-logo

The bootstrapping process shown above will create a project under the current directory with the name silverblue-logo. After this completes, start the application in development mode:

$ ./mvnw compile quarkus:dev

With the application running, check whether it responds as expected by issuing the following command:

$ curl -w '\n' http://localhost:8080/hello

The above command should print hello on the next line. Alternatively, test the application by browsing to http://localhost:8080/hello with your web browser. You should see the same lonely hello on an otherwise empty page. Leave the application running for the next section.

Injection

Open the project in your favorite IDE. If you are using Netbeans, simply open the project directory where the pom.xml file resides. Now would be a good time to have a look at the pom.xml file.

Quarkus uses ArC for its dependency injection. ArC is a dependency of quarkus-resteasy, so it is already part of the core Quarkus installation. Add a companion bean to the project by creating a java class in your IDE called GreetingService.java. Then put the following code into it:

import javax.enterprise.context.ApplicationScoped; @ApplicationScoped
public class GreetingService { public String greeting(String name) { return "hello " + name; } }

The above code is a verbatim copy of what is used in the injection example in the Quarkus Getting Started tutorial. Modify GreetingResource.java by adding the following lines of code:

import javax.inject.Inject;
import org.jboss.resteasy.annotations.jaxrs.PathParam; @Inject GreetingService service;//inject the service @GET //add a getter to use the injected service @Produces(MediaType.TEXT_PLAIN) @Path("/greeting/{name}") public String greeting(@PathParam String name) { return service.greeting(name); }

If you haven’t stopped the application, it will be easy to see the effect of your changes. Just enter the following curl command:

$ curl -w '\n' http://localhost:8080/hello/greeting/Silverblue

The above command should print hello Silverblue on the following line. The URL should work similarly in a web browser. There are two important things to note:

  1. The application was running and Quarkus detected the file changes on the fly.
  2. The injection of code into the app was very easy to perform.

The native image

Next, package your application as a native image that will work in a podman container. Exit the application by pressing CTRL-C. Then use the following command to package it:

$ ./mvnw package -Pnative -Dquarkus.native.container-runtime=podman

Now, build the container:

$ podman build -f src/main/docker/Dockerfile.native -t silverblue-logo/silverblue-logo

Now run it with the following:

$ podman run -i --rm -p 8080:8080 localhost/silverblue-logo/silverblue-logo

To get the container build to successfully complete, it was necessary to copy the /target directory and contents into the src/main/docker/ directory. Investigation as to the reason why is still required, and though the solution used was quick and easy, it is not an acceptable way to solve the problem.

Now that you have the container running with the application inside, you can use the same methods as before to verify that it is working.

Point your browser to the URL http://localhost:8080/ and you should get a index.html that is automatically generated by Quarkus every time you create or modify an application. It resides in the src/main/resources/META-INF/resources/ directory. Drop other HTML files in this resources directory to have Quarkus serve them on request.

For example, create a file named logo.html in the resources directory containing the below markup:

<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html> <head> <title>Silverblue</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div> <img src="fedora-silverblue-logo.png" alt="Fedora Silverblue"/> </div> </body>
</html>

Next, save the below image alongside the logo.html file with the name fedora-silverblue-logo.png:

Now view the results at http://localhost:8080/logo.html.

Testing your application

Quarkus supports junit 5 tests. Look at your project’s pom.xml file. In it you should see two test dependencies. The generated project will contain a simple test, named GreetingResourceTest.java. Testing for the native file is only supported in prod mode. However, you can test the jar file in dev mode. These tests are RestAssured, but you can use whatever test library you wish with Quarkus. Use Maven to run the tests:

$ ./mvnw test

More details can be found in the Quarkus Getting Started tutorial.

Further reading and tutorials

Quarkus has an extensive collection of tutorials and guides. They are well worth the time to delve into the breadth of this microservices framework.

Quarkus also maintains a publications page that lists some very interesting articles on actual use cases of Quarkus. This article has only just scratched the surface of the topic. If what was presented here has piqued your interest, then follow the above links for more information.

Posted on Leave a comment

Fish – A Friendly Interactive Shell

Are you looking for an alternative to bash? Are you looking for something more user-friendly? Then look no further because you just found the golden fish!

Fish (friendly interactive shell) is a smart and user-friendly command line shell that works on Linux, MacOS, and other operating systems. Use it for everyday work in your terminal and for scripting. Scripts written in fish are less cryptic than their equivalent bash versions.

Fish’s user-friendly features

  • Suggestions
    Fish will suggest commands that you have written before. This boosts productivity when typing same commands often.
  • Sane scripting
    Fish avoids using cryptic characters. This provides a clearer and friendlier syntax.
  • Completion based on man pages
    Fish will autocomplete parameters based on the the command’s man page.
  • Syntax highlighting
    Fish will highlight command syntax to make it visually friendly.

Installation

Fedora Workstation

Use the dnf command to install fish:

$ sudo dnf install fish

Make fish your default shell by installing the util-linux-user package and then running the chsh (change shell) command with the appropriate parameters:

$ sudo dnf install util-linux-user
$ chsh -s /usr/bin/fish

You will need to log out and back in for this change to take effect.

Fedora Silverblue

Because this is not GUI application, you will need to layer it using rpm-ostree. Use the following command to install fish on Fedora Silverblue:

$ rpm-ostree install fish

On Fedora Silverblue you will need to reboot your PC to switch to the new ostree image.

If you want to make fish your main shell on Fedora Silverblue, the easiest way is to update the /etc/passwd file. Find your user and change /bin/bash to /usr/bin/fish.

You will need root privileges to edit the /etc/passwd file. Also you will need to log out and back in for this change to take effect.

Configuration

The per-user configuration file for fish is ~/.config/fish/config.fish. To make configuration changes for all users, edit /etc/fish/config.fish instead.

The per-user configuration file must be created manually. The installation scripts will not create ~/.config/fish/config.fish.

Here are a couple configuration examples shown alongside their bash equivalents to get you started:

Creating aliases

  • ~/.bashrc:
    alias ll=’ls -lh’
  • ~/.config/fish/config.fish:
    alias ll=’ls -lh’

Setting environment variables

  • ~/.bashrc:
    export PATH=$PATH:~/bin
  • ~/.config/fish/config.fish:
    set -gx PATH $PATH ~/bin

Working with fish

When fish is configured as your default shell, the command prompt will look similar to what is shown in the below image. If you haven’t configured fish to be your default shell, just run the fish command to start it in your current terminal session.

As you start typing commands, you will notice the syntax highlighting:

Cool, isn’t it? 🙂

You will also see commands being suggested as you type. For example, start typing the previous command a second time:

Notice the gray text that appears as you type. The gray text is fish suggesting the command you wrote before. To autocomplete it, just press CTRL+F.

Get argument suggestions based on the preceding command’s man page by typing a dash () and then the TAB key:

If you press TAB once, it will show you the first few suggestions (or every suggestion, if there are only a few arguments available). If you press TAB a second time, it will show you all suggestions. If you press TAB three times consecutively, it will switch to interactive mode and you can select an argument using the arrow keys.

Otherwise, fish works similar to most other shells. The remaining differences are well documented. So it shouldn’t be difficult to find other features that you may be interested in.

Make fish even more powerful

Make the fish even more powerful with powerline. Powerline adds command execution time, colored git status, current git branch and much more to fish’s interface.

Before installing powerline for fish, you must install Oh My Fish. Oh My Fish extends fish’s core infrastructure to enable the installation of additional plugins. The easiest way to install Oh My Fish is to use the curl command:

> curl -L https://get.oh-my.fish | fish

If you don’t want to pipe the installation commands directly to curl, see the installation section of Oh My Fish’s README for alternative installation methods.

Fish’s powerline plugin is bobthefish. Bobthefish requires the powerline-fonts package.

On Fedora Workstation:

> sudo dnf install powerline-fonts

On Fedora Silverblue:

> rpm-ostree install powerline-fonts

On Fedora Silverblue you will have to reboot to complete the installation of the fonts.

After you have installed the powerline-fonts package, install bobthefish:

> omf install bobthefish

Now you can experience the full awesomeness of fish with powerline:

Additional resources

Check out these web pages to learn even more about fish:

Posted on Leave a comment

Manage tasks and projects on Fedora with Taskwarrior

There are a multitude of applications to manage your todo list. One of these apps is Taskwarrior, it allows you to manage your task in the terminal without a GUI. This article will show you how to get started using it.

What is Taskwarrior?

Taskwarrior is CLI task manager and organizer. It is flexible, fast, and unobtrusive. It does its job then gets out of your way.

Taskwarrior uses $HOME/.taskrc and $HOME/.task to store your settings and tasks respectively.

Getting started with Taskwarrior

It’s easy to use the Taskwarrior to add your daily missions. These are some simple commands. To add tasks:

$ task add buy milk Created task 1. $ task add buy eggs Created task 2. $ task add bake cake Created task 3.

To list your tasks, you can use the task command on its own for the simplest listing:

$ task ID Age Description Urg 1 17s buy milk 0 2 14s buy eggs 0 3 11s bake cake 0 3 tasks.

To mark a task as complete, use the done keyword:

$ task 1 done Completed task 1 'buy milk'. Completed 1 task.
$ task 2 done Completed task 2 'buy eggs'. Completed 1 task.
$ task [task next] ID Age Description Urg 1 57s bake cake 0 1 task

Diving deeper into Taskwarrior

Priority management

Taskwarrior (task) is designed to help prioritize your tasks. To do this, task has multiple implicit and explicit variables it can use to determine an “Urgency” value.

Consider the following list.

$ task [task next] ID Age Description Urg 1 2min buy eggs 0 2 2min buy flour 0 3 2min bake cake 0 4 2min pay rent 0 5 3s install fedora 0 5 tasks

One could argue that paying your rent and installing Fedora have a higher priority than baking a cake. You can tell task about this by using the pri modifier.

$ task 4 mod pri:H Modifying task 4 'pay rent'. Modified 1 task.
$ task 5 mod pri:M Modifying task 5 'install fedora'. Modified 1 task.
$ task [task next] ID Age P Description Urg  4 4min H pay rent 6
 5 2min M install fedora 3.9 1 4min buy eggs 0 2 4min buy flour 0 3 4min bake cake 0 5 tasks

Rent is very important, it has a due date that we need to pay it by, such as within 3 days from the 1st of the month. You can tell task this by using the due modifier.

$ task 4 mod due:3rd Modifying task 4 'pay rent'. Modified 1 task.
$ task [task next] ID Age P Due Description Urg 4 12min H 2d pay rent 13.7 5 10min M install fedora 3.9 1 12min buy eggs 0 2 12min buy flour 0 3 12min bake cake 0 5 tasks
$ date Sat Feb 29 11:59:29 STD 2020

Because the 3rd of next month is nearby, the urgency value of rent has skyrocketed, and will continue to do so once we have reached and passed the due date.

However, not all tasks need to be done right away. Say for example you don’t want to worry about paying your rent until it is posted on the first of the month. You can tell taskwarrior about this using the wait modifier. (Hint: in the following example, som is short for “start of month,” one of the shortcuts taskwarrior understands.)

$ task 4 mod wait:som Modifying task 4 'pay rent'. Modified 1 task.
$ task [task next] ID Age P Description Urg 5 14min M install fedora 3.9 1 16min buy eggs 0 2 16min buy flour 0 3 16min bake cake 0 4 tasks

You will no longer be able to see the pay rent task until the start of the month. You can view waiting tasks by using task waiting:

$ task waiting ID Age P Wait Remaining Due Description 4 18min H 2020-03-01 11h 2020-03-03 pay rent 1 task

There are a few other modifiers you can define. Schedule and until will place a “start” date and remove a task after a date respectfully.

You may have tasks that require other tasks to be completed. To add a dependency for other tasks, use the dep modifier:

$ task [task next] ID Age P Description Urg 5 30min M install fedora 3.9 1 33min buy eggs 0 2 33min buy flour 0 3 33min bake cake 0 4 tasks
$ task 3 mod dep:1,2 Modifying task 3 'bake cake'. Modified 1 task. $ task [task next] ID Age Deps P Description Urg 1 33min buy eggs 8 2 33min buy flour 8 5 31min M install fedora 3.9 3 33min 1 2 bake cake -5 4 tasks

This will modify the priorities of any tasks that is blocking a task. Now buying eggs and flour is more urgent because it is preventing you from performing a task.

Annotations

You can add notes to a task using task <number> annotate:

$ task 3 anno No blueberries Annotating task 3 'bake cake'. Annotated 1 task. $ task [task next] ID Age Deps P Description Urg 1 1h buy eggs 8 2 1h buy flour 8 5 1h M install fedora 3.9 3 1h 1 2 bake cake -4.2 2020-02-29 No blueberries 4 tasks

Organizing tasks

Tasks can being assigned to projects and tags by using the project modifier and adding a tag using the + sign followed by the tag name, such as +problem.

Putting it all together

You can combine everything you learned to create a task in one line with all the required options.

$ task add Write Taskwarrior post \
pri:M due:1m wait:som until:due+2w sche:15th \
project:magazine +taskwarrior +community +linux Created task 6. The project 'magazine' has changed. Project 'magazine' is 0% complete (1 task remaining).
$ task 6 No command specified - assuming 'information'. Name Value ID 6 Description Write Taskwarrior post Status Waiting Project magazine Entered 2020-02-29 13:50:27 (6s) Waiting until 2020-03-01 00:00:00 Scheduled 2020-03-15 00:00:00 Due 2020-03-30 14:50:27 Until 2020-04-13 14:50:27 Last modified 2020-02-29 13:50:27 (6s) Tags taskwarrior community linux Virtual tags SCHEDULED TAGGED UDA UNBLOCKED UNTIL WAITING YEAR LATEST PROJECT PRIORITY UUID 27768737-f6a2-4515-af9d-4f58773c76a5 Urgency 5.3 Priority M

Installing Taskwarrior on Fedora

Taskwarrior is available in the default Fedora repository. To install it use this command with sudo:

$ sudo dnf install task

For rpm-ostree based distributions like Fedora Silverblue:

$ sudo rpm-ostree install task 

Tips and tricks

  • Taskwarrior has a hook system, meaning that there are many tools you can plug in, such as bugwarrior!
  • Taskwarrior can connect to a taskserver for server/client setups. (This is left as an exercise for the reader for now.)

Photo by Bogdan Kupriets on Unsplash.

Posted on Leave a comment

Demonstrating PERL with Tic-Tac-Toe, Part 2

The astute observer may have noticed that PERL is misspelled. In a March 1, 1999 interview with Linux Journal, Larry Wall explained that he originally intended to include the letter “A” from the word “And” in the title “Practical Extraction And Report Language” such that the acronym would correctly spell the word PEARL. However, before he released PERL, Larry heard that another programming language had already taken that name. To resolve the name collision, he dropped the “A”. The acronym is still valid because title case and acronyms allow articles, short prepositions and conjunctions to be omitted (compare for example the acronym LASER).

Name collisions happen when distinct commands or variables with the same name are merged into a single namespace. Because Unix commands share a common namespace, two commands cannot have the same name.

The same problem exists for the names of global variables and subroutines within programs written in languages like PERL. This is an especially significant problem when programmers try to collaborate on large software projects or otherwise incorporate code written by other programmers into their own code base.

Starting with version 5, PERL supports packages. Packages allow PERL code to be modularized with unique namespaces so that the global variables and functions of the modularized code will not collide with the variables and functions of another script or module.

Shortly after its release, PERL5 software developers all over the world began writing software modules to extend PERL’s core functionality. Because many of those developers (currently about 15,000) have made their work freely available on the Comprehensive Perl Archive Network (CPAN), you can easily extend the functionality of PERL on your PC so that you can perform very advanced and complex tasks with just a few commands.

The remainder of this article builds on the previous article in this series by demonstrating how to install, use and create PERL modules on Fedora Linux.

An example PERL program

See the example program from the previous article below, with a few lines of code added to import and use some modules named chip1, chip2 and chip3. It is written in such a way that the program should work even if the chip modules cannot be found. Future articles in this series will build on the below script by adding the additional modules named chip2 and chip3.

You should be able to copy and paste the below code into a plain text file and use the same one-liner that was provided in the previous article to strip the leading numbers.

00 #!/usr/bin/perl
01 02 use strict;
03 use warnings;
04 05 use feature 'state';
06 07 use constant MARKS=>[ 'X', 'O' ];
08 use constant HAL9K=>'O';
09 use constant BOARD=>'
10 ┌───┬───┬───┐
11 │ 1 │ 2 │ 3 │
12 ├───┼───┼───┤
13 │ 4 │ 5 │ 6 │
14 ├───┼───┼───┤
15 │ 7 │ 8 │ 9 │
16 └───┴───┴───┘
17 ';
18 19 use lib 'hal';
20 use if -e 'hal/chip1.pm', 'chip1';
21 use if -e 'hal/chip2.pm', 'chip2';
22 use if -e 'hal/chip3.pm', 'chip3';
23 24 sub get_mark {
25 my $game = shift;
26 my @nums = $game =~ /[1-9]/g;
27 my $indx = (@nums+1) % 2;
28 29 return MARKS->[$indx];
30 }
31 32 sub put_mark {
33 my $game = shift;
34 my $mark = shift;
35 my $move = shift;
36 37 $game =~ s/$move/$mark/;
38 39 return $game;
40 }
41 42 sub get_move {
43 return (<> =~ /^[1-9]$/) ? $& : '0';
44 }
45 46 PROMPT: {
47 no strict;
48 no warnings;
49 50 state $game = BOARD;
51 52 my $mark;
53 my $move;
54 55 print $game;
56 57 if (defined &get_victor) {
58 my $victor = get_victor $game, MARKS;
59 if (defined $victor) {
60 print "$victor wins!\n";
61 complain if ($victor ne HAL9K);
62 last PROMPT;
63 }
64 }
65 66 last PROMPT if ($game !~ /[1-9]/);
67 68 $mark = get_mark $game;
69 print "$mark\'s move?: ";
70 71 if ($mark eq HAL9K and defined &hal_move) {
72 $move = hal_move $game, $mark, MARKS;
73 print "$move\n";
74 } else {
75 $move = get_move;
76 }
77 $game = put_mark $game, $mark, $move;
78 79 redo PROMPT;
80 }

Once you have the above code downloaded and working, create a subdirectory named hal under the same directory that you put the above program. Then copy and paste the below code into a plain text file and use the same procedure to strip the leading numbers. Name the version without the line numbers chip1.pm and move it into the hal subdirectory.

00 # basic operations chip
01 02 package chip1;
03 04 use strict;
05 use warnings;
06 07 use constant MAGIC=>'
08 ┌───┬───┬───┐
09 │ 2 │ 9 │ 4 │
10 ├───┼───┼───┤
11 │ 7 │ 5 │ 3 │
12 ├───┼───┼───┤
13 │ 6 │ 1 │ 8 │
14 └───┴───┴───┘
15 ';
16 17 use List::Util 'sum';
18 use Algorithm::Combinatorics 'combinations';
19 20 sub get_moves {
21 my $game = shift;
22 my $mark = shift;
23 my @nums;
24 25 while ($game =~ /$mark/g) {
26 push @nums, substr(MAGIC, $-[0], 1);
27 }
28 29 return @nums;
30 }
31 32 sub get_victor {
33 my $game = shift;
34 my $marks = shift;
35 my $victor;
36 37 TEST: for (@$marks) {
38 my $mark = $_;
39 my @nums = get_moves $game, $mark;
40 41 next unless @nums >= 3;
42 for (combinations(\@nums, 3)) {
43 my @comb = @$_;
44 if (sum(@comb) == 15) {
45 $victor = $mark;
46 last TEST;
47 }
48 }
49 }
50 51 return $victor;
52 }
53 54 sub hal_move {
55 my $game = shift;
56 my @nums = $game =~ /[1-9]/g;
57 my $rand = int rand @nums;
58 59 return $nums[$rand];
60 }
61 62 sub complain {
63 print "Daisy, Daisy, give me your answer do.\n";
64 }
65 66 sub import {
67 no strict;
68 no warnings;
69 70 my $p = __PACKAGE__;
71 my $c = caller;
72 73 *{ $c . '::get_victor' } = \&{ $p . '::get_victor' };
74 *{ $c . '::hal_move' } = \&{ $p . '::hal_move' };
75 *{ $c . '::complain' } = \&{ $p . '::complain' };
76 }
77 78 1;

The first thing that you will probably notice when you try to run the program with chip1.pm in place is an error message like the following (emphasis added):

$ Can't locate Algorithm/Combinatorics.pm in @INC (you may need to install the Algorithm::Combinatorics module) (@INC contains: hal /usr/local/lib64/perl5/5.30 /usr/local/share/perl5/5.30 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at hal/chip1.pm line 17.
BEGIN failed--compilation aborted at hal/chip1.pm line 17.
Compilation failed in require at /usr/share/perl5/if.pm line 15.
BEGIN failed--compilation aborted at game line 18.

When you see an error like the one above, just use the dnf command to search Fedora’s package repository for the name of the system package that provides the needed PERL module as shown below. Note that the module name and path from the above error message have been prefixed with */ and then surrounded with single quotes.

$ dnf provides '*/Algorithm/Combinatorics.pm'
...
perl-Algorithm-Combinatorics-0.27-17.fc31.x86_64 : Efficient generation of combinatorial sequences
Repo : fedora
Matched from:
Filename : /usr/lib64/perl5/vendor_perl/Algorithm/Combinatorics.pm

Hopefully it will find the needed package which you can then install:

$ sudo dnf install perl-Algorithm-Combinatorics

Once you have all the needed modules installed, the program should work.

How it works

This example is admittedly quite contrived. Nothing about Tic-Tac-Toe is complex enough to need a CPAN module. To demonstrate installing and using a non-standard module, the above program uses the combinations library routine from the Algorithm::Combinatorics module to generate a list of the possible combinations of three numbers from the provided set. Because the board numbers have been mapped to a 3×3 magic square, any set of three numbers that sum to 15 will be aligned on a column, row or diagonal and will therefore be a winning combination.

Modules are imported into a program with the use and require commands. The only difference between them is that the use command automatically calls the import subroutine (if one exists) in the module being imported. The require command does not automatically call any subroutines.

Modules are just files with a .pm extension that contain PERL subroutines and variables. They begin with the package command and end with 1;. But otherwise, they look like any other PERL script. The file name should match the package name. Package and file names are case sensitive.

Beware that when you are reading online documentation about PERL modules, the documentation often veers off into topics about classes. Classes are built on modules, but a simple module does not have to adhere to all the restrictions that apply to classes. When you start seeing words like method, inheritance and polymorphism, you are reading about classes, not modules.

There are two subroutine names that are reserved for special use in modules. They are import and unimport and they are called by the use and no directives respectively.

The purpose of the import and unimport subroutines is typically to alias and unalias the module’s subroutines in and out of the calling namespace respectively. For example, line 17 of chip1.pm shows the sum subroutine being imported from the List::Util module.

The constant module, as used on lines 07 of chip1.pm, is also altering the caller’s namespace (chip1), but rather than importing a predefined subroutine, it is creating a special type of variable.

All the identifiers immediately following the use keywords in the above examples are modules. On my system, many of them can be found under the /usr/share/perl5 directory.

Notice that the above error message states “@INC contains:” followed by a list of directories. INC is a special PERL variable that lists, in order, the directories from which modules should be loaded. The first file found with a matching name will be used.

As demonstrated on line 19 of the Tic-Tac-Toe game, the lib module can be used to update the list of directories in the INC variable.

The chip1 module above provides an example of a very simple import subroutine. In most cases you will want to use the import subroutine that is provided by the Exporter module rather than implementing your own. A custom import subroutine is used in the above example to demonstrate the basics of what it does. Also, the custom implementation makes it easy to override the subroutine definitions in later examples.

The import subroutine shown above reveals some of the hidden magic that makes packages work. All variables that are both globally scoped (that is, created outside of any pair of curly brackets) and dynamically scoped (that is, not prefixed with the keywords my or state) and all global subroutines are automatically prefixed with a package name. The default package name if no package command has been issued is main.

By default, the current package is assumed when an unqualified variable or subroutine is used. When get_move is called from the PROMPT block in the above example, main::get_move is assumed because the PROMPT block exists in the main package. Likewise, when get_moves is called from the get_victor subroutine, chip1::get_moves is assumed because get_victor exists in the chip1 package.

If you want to access a variable or subroutine that exists in a different package, you either have to use its fully qualified name or create a local alias that refers to the desired subroutine.

The import subroutine shown above demonstrates how to create subroutine aliases that refer to subroutines in other packages. On lines 73-75, the fully qualified names for the subroutines are being constructed and then the symbol table name for the subroutine in the calling namespace (the package in which the use statement is being executed) is being assigned the reference of the subroutine in the local package (the package in which the import subroutine is defined).

Notice that subroutines, like variables, have sigils. The sigil for subroutines is the ampersand symbol (&). In most contexts, the sigil for subroutines is optional. When working with references (as shown on lines 73-75 of the import subroutine) and when checking if a subroutine is defined (as shown on lines 57 and 71 of the PROMPT block), the sigil for subroutines is required.

The import subroutine shown above is just a bare minimum example. There is a lot that it doesn’t do. In particular, a proper import subroutine would not automatically import any subroutines or variables. Normally, the user would be expected to provide a list of the routines to be imported on the use line and that list is available to the import subroutine in the @_ array.

Final notes

Lines 25-27 of chip1.pm provide a good example of PERL’s dense notation problem. With just a couple of lines code, the board numbers on which a given mark has been placed can be determined. But does the statement within the conditional clause of the while loop perform the search from the beginning of the game variable on each iteration? Or does it continue from where it left off each time? PERL correctly guesses that I want it to provide the position ($-[0]) of the next mark, if any exits, on each iteration. But exactly what it will do can be very difficult to determine just by looking at the code.

The last things of note in the above examples are the strict and warnings directives. They enable extra compile-time and runtime debugging messages respectively. Many PERL programmers recommend always including these directives so that programming errors are more likely to be spotted. The downside of having them enabled is that some complex code will sometimes cause the debugger to erroneously generate unwanted output. Consequently, the strict and/or warnings directives may need to be disabled in some code blocks to get your program to run correctly as demonstrated on lines 67 and 68 of the example chip1 module. The strict and warnings directives have nothing to do with the program and they can be omitted. Their only purpose is to provide feedback to the program developer.