Posted on Leave a comment

How to turn on an LED with Fedora IoT

Do you enjoy running Fedora, containers, and have a Raspberry Pi? What about using all three together to play with LEDs? This article introduces Fedora IoT and shows you how to install a preview image on a Raspberry Pi. You’ll also learn how to interact with GPIO in order to light up an LED.

What is Fedora IoT?

Fedora IoT is one of the current Fedora Project objectives, with a plan to become a full Fedora Edition. The result will be a system that runs on ARM (aarch64 only at the moment) devices such as the Raspberry Pi, as well as on the x86_64 architecture.

Fedora IoT is based on OSTree, like Fedora Silverblue and the former Atomic Host.

Download and install Fedora IoT

The official Fedora IoT images are coming with the Fedora 29 release. However, in the meantime you can download a Fedora 28-based image for this experiment.

You have two options to install the system: either flash the SD card using a dd command, or use a fedora-arm-installer tool. The Fedora Wiki offers more information about setting up a physical device for IoT. Also, remember that you might need to resize the third partition.

Once you insert the SD card into the device, you’ll need to complete the installation by creating a user. This step requires either a serial connection, or a HDMI display with a keyboard to interact with the device.

When the system is installed and ready, the next step is to configure a network connection. Log in to the system with the user you have just created choose one of the following options:

  • If you need to configure your network manually, run a command similar to the following. Remember to use the right addresses for your network:
    $ nmcli connection add con-name cable ipv4.addresses \ 192.168.0.10/24 ipv4.gateway 192.168.0.1 \ connection.autoconnect true ipv4.dns "8.8.8.8,1.1.1.1" \ type ethernet ifname eth0 ipv4.method manual
  • If there’s a DHCP service on your network, run a command like this:
    $ nmcli con add type ethernet con-name cable ifname eth0

The GPIO interface in Fedora

Many tutorials about GPIO on Linux focus on a legacy GPIO sysfis interface. This interface is deprecated, and the upstream Linux kernel community plan to remove it completely, due to security and other issues.

The Fedora kernel is already compiled without this legacy interface, so there’s no /sys/class/gpio on the system. This tutorial uses a new character device /dev/gpiochipN provided by the upstream kernel. This is the current way of interacting with GPIO.

To interact with this new device, you need to use a library and a set of command line interface tools. The common command line tools such as echo or cat won’t work with this device.

You can install the CLI tools by installing the libgpiod-utils package. A corresponding Python library is provided by the python3-libgpiod package.

Creating a container with Podman

Podman is a container runtime with a command line interface similar to Docker. The big advantage of Podman is it doesn’t run any daemon in the background. That’s especially useful for devices with limited resources. Podman also allows you to start containerized services with systemd unit files. Plus, it has many additional features.

We’ll create a container in these two steps:

  1. Create a layered image containing the required packages.
  2. Create a new container starting from our image.

First, create a file Dockerfile with the content below. This tells podman to build an image based on the latest Fedora image available in the registry. Then it updates the system inside and installs some packages:

FROM fedora:latest RUN  dnf -y update RUN  dnf -y install libgpiod-utils python3-libgpiod

You have created a build recipe of a container image based on the latest Fedora with updates, plus packages to interact with GPIO.

Now, run the following command to build your base image:

$ sudo podman build --tag fedora:gpiobase -f ./Dockerfile

You have just created your custom image with all the bits in place. You can play with this base container images as many times as you want without installing the packages every time you run it.

Working with Podman

To verify the image is present, run the following command:

$ sudo podman images REPOSITORY                 TAG        IMAGE ID       CREATED          SIZE localhost/fedora           gpiobase   67a2b2b93b4b   10 minutes ago  488MB docker.io/library/fedora   latest     c18042d7fac6   2 days ago     300MB

Now, start the container and do some actual experiments. Containers are normally isolated and don’t have an access to the host system, including the GPIO interface. Therefore, you need to mount it inside while starting the container. To do this, use the –device option in the following command:

$ sudo podman run -it --name gpioexperiment --device=/dev/gpiochip0 localhost/fedora:gpiobase /bin/bash

You are now inside the running container. Before you move on, here are some more container commands. For now, exit the container by typing exit or pressing Ctrl+D.

To list the the existing containers, including those not currently running, such as the one you just created, run:

$ sudo podman container ls -a CONTAINER ID   IMAGE             COMMAND     CREATED          STATUS                              PORTS   NAMES 64e661d5d4e8   localhost/fedora:gpiobase   /bin/bash 37 seconds ago Exited (0) Less than a second ago           gpioexperiment

To create a new container, run this command:

$ sudo podman run -it --name newexperiment --device=/dev/gpiochip0 localhost/fedora:gpiobase /bin/bash

Delete it with the following command:

$ sudo podman rm newexperiment

Turn on an LED

Now you can use the container you already created. If you exited from the container, start it again with this command:

$ sudo podman start -ia gpioexperiment

As already discussed, you can use the CLI tools provided by the libgpiod-utils package in Fedora. To list the available GPIO chips, run:

$ gpiodetect gpiochip0 [pinctrl-bcm2835] (54 lines)

To get the list of the lines exposed by a specific chip, run:

$ gpioinfo gpiochip0

Notice there’s no correlation between the number of physical pins and the number of lines printed by the previous command. What’s important is the BCM number, as shown on pinout.xyz. It is not advised to play with the lines that don’t have a corresponding BCM number.

Now, connect an LED to the physical pin 40, that is BCM 21. Remember: the shorter leg of the LED (the negative leg, called the cathode) must be connected to a GND pin of the Raspberry Pi with a 330 ohm resistor, and the long leg (the anode) to the physical pin 40.

To turn the LED on, run the following command. It will stay on until you press Ctrl+C:

$ gpioset --mode=wait gpiochip0 21=1

To light it up for a certain period of time, add the -b (run in the background) and -s NUM (how many seconds) parameters, as shown below. For example, to light the LED for 5 seconds, run:

$ gpioset -b -s 5 --mode=time gpiochip0 21=1

Another useful command is gpioget. It gets the status of a pin (high or low), and can be useful to detect buttons and switches.

Closeup of LED connection with GPIO

Conclusion

You can also play with LEDs using Python — there are some examples here. And you can also use the i2c devices inside the container as well. In addition, Podman is not strictly related to this Fedora edition. You can install it on any existing Fedora Edition, or try it on the two new OSTree-based systems in Fedora: Fedora Silverblue and Fedora CoreOS.

Posted on Leave a comment

How to use VS Code for your Python projects

Visual Studio Code, or VS Code, is an open source code editor that also includes tools for building and debugging an application. With the Python extension enabled, vscode becomes a great working environment for any Python developer. This article shows you which extensions are useful, and how to configure VS Code to get the most out of it.

If you don’t have it installed, check out our previous article, Using Visual Studio Code on Fedora:

Using Visual Studio Code on Fedora

Install the VS Code Python extension

First, to make VS Code Python friendly, install the Python extension from the marketplace.

Once the Python extension installed, you can now configure the Python extension.

VS Code manages its configuration inside JSON files. Two files are used:

  • One for the global settings that applies to all projects
  • One for project specific settings

Press Ctrl+, (comma) to open the global settings.

Setup the Python Path

You can configure VS Code to automatically select the best Python interpreter for each of your projects. To do this, configure the python.pythonPath key in the global settings.

// Place your settings in this file to overwrite default and user settings. { "python.pythonPath":"${workspaceRoot}/.venv/bin/python", }

This sets VS Code to use the Python interpreter located in the project root directory under the .venv virtual environment directory.

Use environment variables

By default, VS Code uses environment variables defined in the project root directory in a .env file. This is useful to set environment variables like:

PYTHONWARNINGS="once"

That setting ensures that warnings are displayed when your program is running.

To change this default, set the python.envFile configuration key as follows:

"python.envFile": "${workspaceFolder}/.env",

Code Linting

The Python extension also supports different code linters (pep8, flake8, pylint). To enable your favorite linter, or the one used by the project you’re working on, you need to set a few configuration items.

By default pylint is enabled. But for this example, configure flake8:

"python.linting.pylintEnabled": false, "python.linting.flake8Path": "${workspaceRoot}/.venv/bin/flake8", "python.linting.flake8Enabled": true, "python.linting.flake8Args": ["--max-line-length=90"],

After enabling the linter, your code is underlined to show where it doesn’t meet criteria enforced by the linter. Note that for this example to work, you need to install flake8 in the virtual environment of the project.

Code Formatting

VS Code also lets you configure automatic code formatting. The extension currently supports autopep8, black and yapf. Here’s how to configure black.

"python.formatting.provider": "black", "python.formatting.blackPath": "${workspaceRoot}/.venv/bin/black" "python.formatting.blackArgs": ["--line-length=90"], "editor.formatOnSave": true,

If you don’t want the editor to format your file on save,  set the option to false and use Ctrl+Shift+I to format the current document. Note that for this example to work, you need to install black in the virtual environment of the project.

Running Tasks

Another great feature of VS Code is that it can run tasks. These tasks are also defined in a JSON file saved in the project root directory.

Run a development flask server

In this example, you’ll create a task to run a Flask development server. Create a new Build using the basic template that can run an external command:

Edit the tasks.json file as follows to create a new task that runs the Flask development server:

{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "Run Debug Server", "type": "shell", "command": "${workspaceRoot}/.venv/bin/flask run -h 0.0.0.0 -p 5000", "group": { "kind": "build", "isDefault": true } } ] }

The Flask development server uses an environment variable to get the entrypoint of the application. Use the .env file to declare these variables. For example:

FLASK_APP=wsgi.py FLASK_DEBUG=True

Now you can execute the task using Ctrl+Shift+B.

Unit tests

VS Code also has the unit test runners pytest, unittest, and nosetest integrated out of the box. After you enable a test runner, VS Code discovers the unit tests and letsyou to run them individually, by test suite, or simply all the tests.

For example, to enable pytest:

"python.unitTest.pyTestEnabled": true, "python.unitTest.pyTestPath": "${workspaceRoot}/.venv/bin/pytest",

Note that for this example to work, you need to install pytest in the virtual environment of the project.

Posted on Leave a comment

Learn how to build your own Twitter bot with Python

Twitter allows one to share blog posts and articles with the world. Using Python and the tweepy library makes it easy to create a Twitter bot that takes care of all the tweeting for you. This article shows you how to build such a bot. Hopefully you can take the concepts here and apply them to other projects that use online services.

Getting started

To create a Twitter bot the tweepy library comes handy. It manages the Twitter API calls and provides a simple interface.

The following commands use Pipenv to install tweepy into a virtual environment. If you don’t have Pipenv installed, check out our previous article, How to install Pipenv on Fedora.

$ mkdir twitterbot $ cd twitterbot $ pipenv --three $ pipenv install tweepy $ pipenv shell

Tweepy – Getting started

To use the Twitter API the bot needs to authenticate against Twitter. For that, tweepy uses the OAuth authentication standard. You can get credentials by creating a new application at https://apps.twitter.com/.

Create a new Twitter application

After you fill in the following form and click on the Create your Twitter application button, you have access to the application credentials. Tweepy requires the Consumer Key (API Key) and the Consumer Secret (API Secret), both available from the Keys and Access Tokens.

After scrolling down the page, generate an Access Token and an Access Token Secret using the Create my access token button.

Using Tweepy – print your timeline

Now that you have all the credentials needed, open a new file and write the following Python code.

import tweepy auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret") auth.set_access_token("your_access_token", "your_access_token_secret") api = tweepy.API(auth) public_tweets = api.home_timeline() for tweet in public_tweets: print(tweet.text)

After making sure that you are using the Pipenv virtual environment, run your program.

$ python tweet.py

The above program calls the home_timeline API method to retrieve the 20 most recent tweets from your timeline. Now that the bot is able to use tweepy  to get data from Twitter, try changing the code to send a tweet.

Using Tweepy – send a tweet

To send a tweet, the API method update_status comes in handy. The usage is simple:

api.update_status("The awesome text you would like to tweet")

The tweepy library has many other methods that can be useful for a Twitter bot. For the full details of the API, check the documentation.

A magazine bot

Let’s create a bot that searches for Fedora Magazine tweets and automatically retweets them.

To avoid retweeting the same tweet multiple times, the bot stores the tweet ID of the last retweet. Two helper functions, store_last_id and get_last_id, will be used to save and retrieve this ID.

Then the bot uses the tweepy search API to find the Fedora Magazine tweets that are more recent than the stored ID.

import tweepy def store_last_id(tweet_id): """ Store a tweet id in a file """ with open("lastid", "w") as fp: fp.write(str(tweet_id)) def get_last_id(): """ Read the last retweeted id from a file """ with open("lastid", "r") as fp: return fp.read() if __name__ == '__main__': auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret") auth.set_access_token("your_access_token", "your_access_token_secret") api = tweepy.API(auth) try: last_id = get_last_id() except FileNotFoundError: print("No retweet yet") last_id = None for tweet in tweepy.Cursor(api.search, q="fedoramagazine.org", since_id=last_id).items(): if tweet.user.name == 'Fedora Project': store_last_id(tweet.id) tweet.retweet() print(f'"{tweet.text}" was retweeted'

In order to retweet only tweets from the Fedora Magazine, the bot searches for tweets that contain fedoramagazine.org and are published by the “Fedora Project” Twitter account.

Conclusion

In this article you saw how  to create a Twitter application using the tweepy Python library to automate reading, sending and searching tweets. You can now use your creativity to create a Twitter bot of your own.

The source code of the example in this article is available on Github.

Posted on Leave a comment

Anaconda improvements in Fedora 28

Fedora 28 was released last month, and the major update brought with it a raft of new features for the Fedora Installer (Anaconda).  Like Fedora, Anaconda is a dynamic software project with new features and updates every release. Some changes are user visible, while others happen under the hood — making Anaconda more robust and prepared for future improvements.

User & Root configuration on Fedora Workstation

When installing Fedora Workstation from the Live media, the user and root configuration screens are no longer in the installer. Setting up users is now only done in the Initial Setup screens after installation.

The progress hub on a Fedora 28 Workstation live installation.

The progress hub on a Fedora 28 Workstation live installation.

The back story is that the Fedora Workstation working group aimed to reduce the number of screens users see during installation.  Primarily, this included screens that let a user set option twice: both Anaconda and the Gnome Initial Setup tool upon first boot. The working group considered various options, such as Anaconda reporting which screens have been visited by the user and then hiding them in Gnome Initial Setup. In the end they opted for just always skipping the user and root configuration screens in Anaconda and just configuring a user with sudo rights in Gnome Initial Setup.

Because of this the respective screen (user creation) shows up just once (in Gnome Initial Setup), making the installation experience more consistent.

It’s also worth noting that this change only affects the Fedora Workstation live image. All other images, including the Fedora Workstation netinst image and other live images, are unaffected.

Anaconda on DBus

Last year we announced the commencement of our next major initiative — modularizing Anaconda. The main idea is to split the code into several modules that will communicate over DBus. This will provide better stability, extensibility and testability of Anaconda.

Fedora 28 is the first release where Anaconda operates via DBus. At startup, Anaconda starts its private message bus and ten simple modules. For now, the modules just hold data that are provided by a kickstart file and modified by the UI. The UI uses the data to drive installation. This means that you can use DBus to monitor current settings, but you should use the UI to change them.

You can easily explore the current Anaconda DBus API with the live version of Fedora Workstation 28. Just keep in mind that the API is still unstable, so it might change in the future.

To do so, boot the live image and install the D-Feet application:

sudo dnf install d-feet

Start the installer and get an address of the Anaconda message bus:

cat /var/run/anaconda/bus.address

Start D-Feet, choose the option ‘Connect to other Bus’ and copy the first part of the Anaconda bus address to the text field (see the picture below). Click on the ‘Connect’ button. The application will open a new tab and show you a list of available DBus services. Now you can view the interfaces, methods, signals and properties of Anaconda DBus modules and interact with them.

Connecting to the Anaconda DBUS session.

Connecting to the Anaconda DBUS session.

The Anaconda DBUS API as visible in D-Feet.

The Anaconda DBUS API as visible in D-Feet.

Blivet 3.0 and Pykickstart 3.0

Fedora 28 provides version 3 of blivet and Pykickstart, and Anaconda uses the updated versions too.  While this is not really visible from end user perspective, changes like this are important to assure a robust and maintainable future for the Anaconda installer.

The main change in Pykickstart 3 is the switch from the deprecated optparse module to argparse for kickstart parsing. This not only brings all the features argparse has, it was also one of the prerequisites for having automatically generated kickstart documentation on Read the Docs.

Blivet 3 is less radical  update, but includes significant API improvements and cleanups. Some installer-related code still sitting in Blivet was finally moved to Anaconda.

Migrating from authconfig to authselect

The authconfig tool is deprecated and replaced with authselect in Fedora 28, so Anaconda deprecated the kickstart command authconfig and introduced a new command: authselect. You can still use the authconfig command, but Anaconda will install and run the authselect-compat tool instead.

Enabled hibernation

Previously, Hibernation didn’t work after installation because of a missing kernel option, so it had to be set up manually. Starting with Fedora 28, Anaconda adds the kernel option ‘resume’ with a path to the largest available swap device by default on x86 architectures.

Reducing Initial Setup dependencies

The Initial Setup tool is basically a lightweight launcher for arbitrary configuration screens from Anaconda. And while Anaconda often runs from a dedicated installation image, Initial Setup always runs directly on the installed system. This also means all the dependencies of Initial Setup will end up on users system, and unless they are uninstalled, they will take up space more or less forever.

The situation is even more dire on ARM, where users generally just dd a Fedora image to memory card or internal storage on the ARM board and Initial Setup basically acts as the installer, customizing the otherwise identical image for the given user. In this case Initial Setup dependencies directly dictate how small the Fedora image can be.

In Fedora 28, the new anaconda-install-env-deps metapackage  depends on all installation-time-only dependencies. The anaconda-install-env-deps package is always installed on installation images (netinst, live), but is not an Initial Setup dependency and should thus prevent all the unnecessary packages from being pulled in to the installed system. There is also a nice side effect of finally consolidating all the install-time-only dependencies in the Anaconda spec file.

 

Posted on Leave a comment

Download an OS with GNOME Boxes

Boxes is the GNOME application for running virtual machines. Recently Boxes added a new feature that makes it easier to run different Linux distributions. You can now automatically install these distros in Boxes, as well as operating systems like FreeBSD and FreeDOS. The list even includes Red Hat Enterprise Linux. The Red Hat Developer Program includes a no-cost subscription to Red Hat Enterprise Linux. With a Red Hat Developer account, Boxes can automatically set up a RHEL virtual machine entitled to the Developer Suite subscription. Here’s how it works.

 

Red Hat Enterprise Linux

To create a Red Hat Enterprise Linux virtual machine, launch Boxes and click New. Select Download an OS from the source selection list. At the top, pick Red Hat Enterprise Linux. This opens a web form at developers.redhat.com. Sign in with an existing Red Hat Developer Account, or create a new one.

If this is a new account, Boxes requires some additional information before continuing. This step is required to enable the Developer Subscription on the account. Be sure to accept the Terms & Conditions now too. This saves a step later during registration.

 

Click Submit and the installation disk image starts to download. The download can take a while, depending on your Internet connection. This is a great time to go fix a cup of tea or coffee!

Once the media has downloaded (conveniently to ~/Downloads), Boxes offers to perform an Express Install. Fill in the account and password information and click Continue. Click Create after you verify the virtual machine details. The Express Install  automatically performs the entire installation! (Now is a great time to enjoy a second cup of tea or coffee, if so inclined.)

Once the installation is done, the virtual machine reboots and logs directly into the desktop. Inside the virtual machine, launch the Red Hat Subscription Manager via the Applications menu, under System Tools. Enter the root password to launch the utility.

Click the Register button and follow the steps through the registration assistant. Log in with your Red Hat Developers account when prompted.

Now you can download and install updates through any normal update method, such as yum or GNOME Software.

FreeDOS anyone?

Boxes can install a lot more than just Red Hat Enterprise Linux, too. As a front end to KVM and qemu, Boxes supports a wide variety of operating systems. Using libosinfo, Boxes can automatically download (and in some cases, install) quite a few different ones.

To install an OS from the list, select it and finish creating the new virtual machine. Some OSes, like FreeDOS, do not support an Express Install. In those cases the virtual machine boots from the installation media. You can then manually install.

Popular operating systems on Boxes

These are just a few of the popular choices available in Boxes today.

Ubuntu 17.10

Pop!_OS 17.10

EndlessOS 3

Fedora 28

openSUSE Tumbleweed

Debian 9

Fedora updates its osinfo-db package regularly. Be sure to check back frequently for new OS options.