Open-source News

15 | February | 2023 - Hackaday

Google News - Wed, 02/15/2023 - 17:06
15 | February | 2023  Hackaday

Manage OpenStack using Terraform and GitLab

opensource.com - Wed, 02/15/2023 - 16:00
Manage OpenStack using Terraform and GitLab ajscanlas Wed, 02/15/2023 - 03:00

One virtue of GitOps is Infrastructure as Code. It encourages collaboration by using a shared configuration and policy repository. Using GitLab can further enhance collaboration in your OpenStack cluster. GitLab CI can serve as your source control and orchestration hub for CI/CD, and it can even manage the state of Terraform.

To achieve this, you need the following:

  1. GitLab account or instance.
  2. Private OpenStack cluster. If you don't have one, read my article Set up OpenStack on a Raspberry Pi cluster.
  3. A computer (preferably a container host).
GitLab and Terraform state

The goal is to achieve collaboration through Terraform, so you need to have a centralized state file. GitLab has a managed state for Terraform. With this feature, you can enable individuals to manage OpenStack collaboratively.

Create a GitLab group and project

Log in to GitLab, click on the hamburger menu, and click GroupsView all groups.

Image by:

(AJ Canlas, CC BY-SA 4.0)

Create a group by clicking on New group and then on Create group.

Image by:

(AJ Canlas, CC BY-SA 4.0)

Name the group to generate a unique group URL, and invite your team to work with you.

Image by:

(AJ Canlas, CC BY-SA 4.0)

After creating a group, create a project by clicking Create new project, and then Create blank project:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Name your project. GitLab generates a unique project URL for you. This project contains the repository for your Terraform scripts and Terraform state.

Create a personal access token

The repository needs a personal access token to manage this Terraform state. In your profile, select Edit Profile:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Click Access Token in the side panel to access a menu for creating an access token. Save your token because you can't view it again.

Image by:

(AJ Canlas, CC BY-SA 4.0)

Clone the empty repository

On a computer with direct access to your OpenStack installation, clone the repository and then change to the resulting directory:

$ git clone git@gitlab.com:testgroup2170/testproject.git $ cd testprojectCreate the backend .tf and provider file

Create a backend file to configure GitLab as your state backend:

$ cat >> backend.tf << EOF terraform { backend "http" { } } EOF

This provider file pulls the provider for OpenStack:

$ cat >> provider.tf << EOF terraform { required_version = ">= 0.14.0" required_providers { openstack = { source = "terraform-provider-openstack/openstack" version = "1.49.0" } } } provider "openstack" { user_name = var.OS_USERNAME tenant_name = var.OS_TENANT password = var.OS_PASSWORD auth_url = var.OS_AUTH_URL region = var.OS_REGION } EOF

Because you've declared a variable in the provider, you must declare it in a variable file:

$ cat >> variables.tf << EOF variable "OS_USERNAME" { type = string description = "OpenStack Username" } variable "OS_TENANT" { type = string description = "OpenStack Tenant/Project Name" } variable "OS_PASSWORD" { type = string description = "OpenStack Password" } variable "OS_AUTH_URL" { type = string description = "OpenStack Identitiy/Keystone API for authentication" } variable "OS_REGION" { type = string description = "OpenStack Region" } EOF

Because you're initially working locally, you must set those variables to make it work:

$ cat >> terraform.tfvars << EOF OS_USERNAME = "admin" OS_TENANT = "admin" OS_PASSWORD = "YYYYYYYYYYYYYYYYYYYYYY" OS_AUTH_URL = "http://X.X.X.X:35357/v3" OS_REGION = "RegionOne" EOF

These details are available on your rc file on OpenStack.

Initialize the project in Terraform

Initializing the project is quite different because you need to tell Terraform to use GitLab as your state backend:

PROJECT_ID="" TF_USERNAME="" TF_PASSWORD="" TF_STATE_NAME="" TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/${TF_STATE_NAME}" $ terraform init \ -backend-config=address=${TF_ADDRESS} \ -backend-config=lock_address=${TF_ADDRESS}/lock \ -backend-config=unlock_address=${TF_ADDRESS}/lock \ -backend-config=username=${TF_USERNAME} \ -backend-config=password=${TF_PASSWORD} \ -backend-config=lock_method=POST \ -backend-config=unlock_method=DELETE \ -backend-config=retry_wait_min=5

To view the gitlab-project-id, look in the project details just above the Project Information tab in the side panel. It's usually your project name.

Image by:

(AJ Canlas, CC BY-SA 4.0)

For me, it's 42580143.

Use your username for gitlab-username. Mine is ajohnsc.

The gitlab-personal-access-token is the token you created earlier in this exercise. In this example, I use wwwwwwwwwwwwwwwwwwwww. You can name your-unique-state-name anything. I used homelab.

Here is my initialization script:

PROJECT_ID="42580143" TF_USERNAME="ajohnsc" TF_PASSWORD="wwwwwwwwwwwwwwwwwwwww" TF_STATE_NAME="homelab" TF_ADDRESS="https://gitlab.com/api/v4/projects/${PROJECT_ID}/terraform/state/${TF_STATE_NAME}"

To use the file:

$ terraform init \ -backend-config=address=${TF_ADDRESS} \ -backend-config=lock_address=${TF_ADDRESS}/lock \ -backend-config=unlock_address=${TF_ADDRESS}/lock \ -backend-config=username=${TF_USERNAME} \ -backend-config=password=${TF_PASSWORD} \ -backend-config=lock_method=POST \ -backend-config=unlock_method=DELETE \ -backend-config=retry_wait_min=5

The output is similar to this:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Test the Terraform script

This sets the size of the VMs for my OpenStack flavors:

$ cat >> flavors.tf << EOF resource "openstack_compute_flavor_v2" "small-flavor" { name = "small" ram = "4096" vcpus = "1" disk = "0" flavor_id = "1" is_public = "true" } resource "openstack_compute_flavor_v2" "medium-flavor" { name = "medium" ram = "8192" vcpus = "2" disk = "0" flavor_id = "2" is_public = "true" } resource "openstack_compute_flavor_v2" "large-flavor" { name = "large" ram = "16384" vcpus = "4" disk = "0" flavor_id = "3" is_public = "true" } resource "openstack_compute_flavor_v2" "xlarge-flavor" { name = "xlarge" ram = "32768" vcpus = "8" disk = "0" flavor_id = "4" is_public = "true" } EOF

The settings for my external network are as follows:

$ cat >> external-network.tf << EOF resource "openstack_networking_network_v2" "external-network" { name = "external-network" admin_state_up = "true" external = "true" segments { network_type = "flat" physical_network = "physnet1" } } resource "openstack_networking_subnet_v2" "external-subnet" { name = "external-subnet" network_id = openstack_networking_network_v2.external-network.id cidr = "10.0.0.0/8" gateway_ip = "10.0.0.1" dns_nameservers = ["10.0.0.254", "10.0.0.253"] allocation_pool { start = "10.0.0.2" end = "10.0.254.254" } } EOF

Router settings look like this:

$ cat >> routers.tf << EOF resource "openstack_networking_router_v2" "external-router" { name = "external-router" admin_state_up = true external_network_id = openstack_networking_network_v2.external-network.id } EOF

Enter the following for images:

$ cat >> images.tf << EOF resource "openstack_images_image_v2" "cirros" { name = "cirros" image_source_url = "https://download.cirros-cloud.net/0.6.1/cirros-0.6.1-x86_64-disk.img" container_format = "bare" disk_format = "qcow2" } EOF

Here is a Demo tenant:

$ cat >> demo-project-user.tf << EOF resource "openstack_identity_project_v3" "demo-project" { name = "Demo" } resource "openstack_identity_user_v3" "demo-user" { name = "demo-user" default_project_id = openstack_identity_project_v3.demo-project.id password = "demo" } EOF

When complete, you will have this file structure:

. ├── backend.tf ├── demo-project-user.tf ├── external-network.tf ├── flavors.tf ├── images.tf ├── provider.tf ├── routers.tf ├── terraform.tfvars └── variables.tfIssue plan

After the files are complete, you can create the plan files with the terraform plan command:

$ terraform plan Acquiring state lock. This may take a few moments... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # openstack_compute_flavor_v2.large-flavor will be created + resource "openstack_compute_flavor_v2" "large-flavor" { + disk = 0 + extra_specs = (known after apply) + flavor_id = "3" + id = (known after apply) + is_public = true + name = "large" + ram = 16384 + region = (known after apply) + rx_tx_factor = 1 + vcpus = 4 } [...] Plan: 10 to add, Releasing state lock. This may take a few moments...

After all plan files have been created, apply them with the terraform apply command:

$ terraform apply -auto-approve Acquiring state lock. This may take a few moments... [...] Plan: 10 to add, 0 to change, 0 to destroy. openstack_compute_flavor_v2.large-flavor: Creating... openstack_compute_flavor_v2.small-flavor: Creating... openstack_identity_project_v3.demo-project: Creating... openstack_networking_network_v2.external-network: Creating... openstack_compute_flavor_v2.xlarge-flavor: Creating... openstack_compute_flavor_v2.medium-flavor: Creating... openstack_images_image_v2.cirros: Creating... [...] Releasing state lock. This may take a few moments... Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

After applying the infrastructure, return to GitLab and navigate to your project. Look in InfrastructureTerraform to confirm that the state homelab has been created.

Image by:

(AJ Canlas, CC BY-SA 4.0)

Destroy the state to test CI

Now that you've created a state, try destroying the infrastructure so you can apply the CI pipeline later. Of course, this is purely for moving from Terraform CLI to a Pipeline. If you have an existing infrastructure, you can skip this step.

$ terraform destroy -auto-approve Acquiring state lock. This may take a few moments... openstack_identity_project_v3.demo-project: Refreshing state... [id=5f86d4229003404998dfddc5b9f4aeb0] openstack_networking_network_v2.external-network: Refreshing state... [id=012c10f3-8a51-4892-a688-aa9b7b43f03d] [...] Plan: 0 to add, 0 to change, 10 to destroy. openstack_compute_flavor_v2.small-flavor: Destroying... [id=1] openstack_compute_flavor_v2.xlarge-flavor: Destroying... [id=4] openstack_networking_router_v2.external-router: Destroying... [id=73ece9e7-87d7-431d-ad6f-09736a02844d] openstack_compute_flavor_v2.large-flavor: Destroying... [id=3] openstack_identity_user_v3.demo-user: Destroying... [id=96b48752e999424e95bc690f577402ce] [...] Destroy complete! Resources: 10 destroyed.

You now have a state everyone can use. You can provision using a centralized state. With the proper pipeline, you can automate common tasks.

Set up a GitLab runner

Your OpenStack cluster isn't public-facing, and the OpenStack API isn't exposed. You must have a GitLab runner to run GitLab pipelines. GitLab runners are services or agents that run and perform tasks on the remote GitLab server.

On a computer on a different network, create a container for a GitLab runner:

$ docker volume create gitlab-runner-config $ docker run -d --name gitlab-runner --restart always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v gitlab-runner-config:/etc/gitlab-runner \ gitlab/gitlab-runner:latest $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 880e2ed289d3 gitlab/gitlab-runner:latest "/usr/bin/dumb-init …" 3 seconds ago Up 2 seconds gitlab-runner-test

Now register it with your project in your GitLab project's SettingsCI/CD panel:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Scroll down to RunnersCollapse:

Image by:

(AJ Canlas, CC BY-SA 4.0)

The GitLab runner registration token and URL are required. Disable the shared runner on the right side to ensure it works on the runner only. Run the gitlab-runner container to register the runner:

$ docker exec -ti gitlab-runner /usr/bin/gitlab-runner register Runtime platform arch=amd64 os=linux pid=18 revision=6d480948 version=15.7.1 Running in system-mode. Enter the GitLab instance URL (for example, https://gitlab.com/): https://gitlab.com/ Enter the registration token: GR1348941S1bVeb1os44ycqsdupRK Enter a description for the runner: [880e2ed289d3]: dockerhost Enter tags for the runner (comma-separated): homelab Enter optional maintenance note for the runner: WARNING: Support for registration tokens and runner parameters in the 'register' command has been deprecated in GitLab Runner 15.6 and will be replaced with support for authentication tokens. For more information, see https://gitlab.com/gitlab-org/gitlab/-/issues/380872 Registering runner... succeeded runner=GR1348941S1bVeb1o Enter an executor: docker-ssh, shell, virtualbox, instance, kubernetes, custom, docker, parallels, ssh, docker+machine, docker-ssh+machine: docker Enter the default Docker image (for example, ruby:2.7): ajscanlas/homelab-runner:3.17 Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"

Upon success, your GitLab interface displays your runner as valid. It looks like this:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Explore the open source cloud Free online course: Developing cloud-native applications with microservices eBook: Modernize your IT with managed cloud services Try for 60 days: Red Hat OpenShift Dedicated Free online course: Containers, Kubernetes and Red Hat OpenShift What is Kubernetes? Understanding edge computing Latest articles for IT architects

You can now use that runner to automate provisioning with a CI/CD pipeline in GitLab.

Set up the GitLab pipeline

Now you can set up a pipeline. Add a file named .gitlab-ci.yaml in your repository to define your CI/CD steps. Ignore the files you don't need, like .terraform directories and sensitive data like variable files.

Here's my .gitignore file:

$ cat .gitignore *.tfvars .terraform*

Here are my CI pipeline entries in .gitlab-ci.yaml:

$ cat .gitlab-ci.yaml default: tags: - homelab variables: TF_ROOT: ${CI_PROJECT_DIR} TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/homelab cache: key: homelab paths: - ${TF_ROOT}/.terraform* stages: - prepare - validate - build - deploy before_script: - cd ${TF_ROOT} tf-init: stage: prepare script: - terraform --version - terraform init -backend-config=address=${BE_REMOTE_STATE_ADDRESS} -backend-config=lock_address=${BE_REMOTE_STATE_ADDRESS}/lock -backend-config=unlock_address=${BE_REMOTE_STATE_ADDRESS}/lock -backend-config=username=${BE_USERNAME} -backend-config=password=${BE_ACCESS_TOKEN} -backend-config=lock_method=POST -backend-config=unlock_method=DELETE -backend-config=retry_wait_min=5 tf-validate: stage: validate dependencies: - tf-init variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform validate tf-build: stage: build dependencies: - tf-validate variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform plan -out "planfile" artifacts: paths: - ${TF_ROOT}/planfile tf-deploy: stage: deploy dependencies: - tf-build variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform apply -auto-approve "planfile"

The process starts by declaring that every step and stage is under the homelab tag, allowing your GitLab runner to run it.

default: tags: - homelab

Next, the variables are set on the pipeline. The variables are only present when the pipeline is running:

variables: TF_ROOT: ${CI_PROJECT_DIR} TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/homelab

There's a cache that saves specific files and directories upon running from stage to stage:

cache: key: homelab paths: - ${TF_ROOT}/.terraform*

These are the stages that the pipeline follows:

stages: - prepare - validate - build - deploy

This declares what to do before any stages are run:

before_script: - cd ${TF_ROOT}

In the prepare stage, the tf-init initializes the Terraform scripts, gets the provider, and sets its backend to GitLab. Variables that aren't declared yet are added as environment variables later.

tf-init: stage: prepare script: - terraform --version - terraform init -backend-config=address=${BE_REMOTE_STATE_ADDRESS} -backend-config=lock_address=${BE_REMOTE_STATE_ADDRESS}/lock -backend-config=unlock_address=${BE_REMOTE_STATE_ADDRESS}/lock -backend-config=username=${BE_USERNAME} -backend-config=password=${BE_ACCESS_TOKEN} -backend-config=lock_method=POST -backend-config=unlock_method=DELETE -backend-config=retry_wait_min=5

In this part, the CI job tf-validate and the stage validate run Terraform to validate that the Terraform scripts are free of syntax errors. Variables not yet declared are added as environment variables later.

tf-validate: stage: validate dependencies: - tf-init variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform validate

Next, the CI job tf-build with the stage build creates the plan file using terraform plan and temporarily saves it using the artifacts tag.

tf-build: stage: build dependencies: - tf-validate variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform plan -out "planfile" artifacts: paths: - ${TF_ROOT}/planfile

In the next section, the CI job tf-deploy with the stage deploy applies the plan file.

tf-deploy: stage: deploy dependencies: - tf-build variables: TF_VAR_OS_AUTH_URL: ${OS_AUTH_URL} TF_VAR_OS_PASSWORD: ${OS_PASSWORD} TF_VAR_OS_REGION: ${OS_REGION} TF_VAR_OS_TENANT: ${OS_TENANT} TF_VAR_OS_USERNAME: ${OS_USERNAME} script: - terraform apply -auto-approve "planfile"

There are variables, so you must declare them in SettingsCI/CDVariablesExpand.

Image by:

(AJ Canlas, CC BY-SA 4.0)

Add all the variables required:

BE_ACCESS_TOKEN => GitLab Access Token BE_REMOTE_STATE_ADDRESS => This was the rendered TF_ADDRESS variable BE_USERNAME => GitLab username OS_USERNAME => OpenStack Username OS_TENANT => OpenStack tenant OS_PASSWORD => OpenStack User Password OS_AUTH_URL => Auth URL OS_REGION => OpenStack Region

So for this example, I used the following:

BE_ACCESS_TOKEN = "wwwwwwwwwwwwwwwwwwwww" BE_REMOTE_STATE_ADDRESS = https://gitlab.com/api/v4/projects/42580143/terraform/state/homelab BE_USERNAME = "ajohnsc" OS_USERNAME = "admin" OS_TENANT = "admin" OS_PASSWORD = "YYYYYYYYYYYYYYYYYYYYYY" OS_AUTH_URL = "http://X.X.X.X:35357/v3" OS_REGION = "RegionOne"

And it is masked GitLab for its protection.

Image by:

(AJ Canlas, CC BY-SA 4.0)

The last step is to push the new files to the repository:

$ git add . $ git commit -m "First commit" [main (root-commit) e78f701] First commit 10 files changed, 194 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 backend.tf create mode 100644 demo-project-user.tf create mode 100644 external-network.tf create mode 100644 flavors.tf create mode 100644 images.tf create mode 100644 provider.tf create mode 100644 routers.tf create mode 100644 variables.tf $ git push Enumerating objects: 12, done. Counting objects: 100% (12/12), done. Delta compression using up to 4 threads Compressing objects: 100% (10/10), done. Writing objects: 100% (12/12), 2.34 KiB | 479.00 KiB/s, done. Total 12 (delta 0), reused 0 (delta 0), pack-reused 0 To gitlab.com:testgroup2170/testproject.git * [new branch] main -> mainView the results

View your new pipelines in the CI/CD section of GitLab.

Image by:

(AJ Canlas, CC BY-SA 4.0)

On the OpenStack side, you can see the resources created by Terraform.

The networks:

Image by:

(AJ Canlas, CC BY-SA 4.0)

The flavors:

Image by:

(AJ Canlas, CC BY-SA 4.0)

The images:

Image by:

(AJ Canlas, CC BY-SA 4.0)

The project:

Image by:

(AJ Canlas, CC BY-SA 4.0)

The user:

Image by:

(AJ Canlas, CC BY-SA 4.0)

Next steps

Terraform has so much potential. Terraform and Ansible are great together. In my next article, I'll demonstrate how Ansible can work with OpenStack

Follow this tutorial to see how using GitLab can further enhance collaboration in your OpenStack cluster.

Image by:

Opensource.com

Containers OpenStack Git GitLab Cloud CI/CD Automation What to read next This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. Register or Login to post a comment.

How I use Ansible to add a feature to my Linux KDE desktop

opensource.com - Wed, 02/15/2023 - 16:00
How I use Ansible to add a feature to my Linux KDE desktop sethkenlon Wed, 02/15/2023 - 03:00

I run the KDE Plasma Desktop on my computer because it's a flexible environment with lots of options for customization. Having choices in your desktop is about more than just having lots of menus and buttons to activate or deactivate. The thing I love most about KDE Plasma Desktop is the ability to add my own features to it. One reason this is possible is KServices, a simple but powerful plugin framework for handling desktop services.

Add functions to the right-click menu

In the KDE Plasma Desktop, there's usually a contextual menu available when you right-click on something, such as a directory or a file. You can add items to the right-click menu by creating your own KService, and you don't need anything more than a rudimentary understanding of Bash to make it work.

First, create a new directory for your service menu:

$ mkdir -p ~/.local/share/kio/servicemenus

Add a .desktop file:

$ touch ~/.local/share/kio/servicemenus/hello.desktop

Open the hello.desktop file in a text editor. A .desktop file is a small configuration file used by the menu system of the Linux desktop. Here's a simple KServices file that generates a hello.txt file in the directory you select:

[Desktop Entry] Type=Service MimeType=inode/directory; Actions=Hello [Desktop Action Hello] Name=Say hello Icon=/usr/share/icons/breeze-dark/actions/symbolic/file-library-symbolic.svg Exec=touch %f/hello.txt
  • The first configuration block tells your system that this .desktop file is a service rather than, for instance, an application.

  • The MimeType tells the Plasma Desktop to only show this action as an option when you right-click on a folder, not a file.

  • The Actions line identifies what action is taken when this service is activated. The name Hello is arbitrary, and refers to the next configuration block, which is a Desktop Action configuration with the name Hello.

Here's what the next configuration block means:

  • The Desktop Action definition named Hello.

  • The values for Name and Icon appear in the right-click menu.

  • The Exec line is the command you want to run when your service is selected. As a simple demonstration, this .desktop file just creates an empty file called hello.txt in the location that you right-clicked on (represented by the special variable %f).

Save the .desktop file, and then make it executable:

$ chmod +x ~/.local/share/kio/servicemenus/hello.desktop

Start a new instance of the Dolphin file manager and create an empty folder. Then right-click on the folder and navigate to Actions. In the Actions menu, there's a new service available, and it's called Say hello because that's what your .desktop file has set in the Name field.

Image by:

(Seth Kenlon, CC BY-SA 4.0)

Look in the folder after running the service to see the empty hello.txt file that's been created.

Mimetypes

This sample KService only works on directories because the .desktop file defining the service specifies the Mimetype: inode/directory. That's what tells Dolphin not to display the service when you right-click on a file.

Using mimetypes, you can create highly specific services based on what kind of file system object you select when you right-click. The perl-file-mimeinfo package provides a mimetype command, which you can use to get the mimetype of any file. Install it with your distribution's package manager, and then try it out:

$ mimetype example.txt example.txt: text/plain $ mimetype Photos/example.webp Photos/example.webp: image/webp

More Linux resources Linux commands cheat sheet Advanced Linux commands cheat sheet Free online course: RHEL technical overview Linux networking cheat sheet SELinux cheat sheet Linux common commands cheat sheet What are Linux containers? Our latest Linux articles Executables

I demonstrated a simple "hello world" example in this article, but KServices can be as complex as you need them to be. The Exec line of your KService .desktop file can launch any application or script, and the %f variable ensures that the target or destination of whatever gets launched is what you've right-clicked on.

For my own workflow, I used to use Planter to quickly construct a project environment. Lately, though, I've switched to Ansible and this KService:

[Desktop Entry] Type=Service MimeType=inode/directory; Actions=planter [Desktop Action planter] Name=Create project directory Icon=/usr/share/icons/breeze-dark/actions/symbolic/folder-new-symbolic.svg Exec=ansible-playbook /home/seth/Ansible/playbooks/standard_dirs.yaml -e dir=%f

Here's my Ansible playbook:

--- - hosts: localhost tasks: - name: Create directories ansible.builtin.file: path: "{{ item }}" state: directory with_items: - '{{ dir }}/video' - '{{ dir }}/edit' - '{{ dir }}/audio' - '{{ dir }}/title' - '{{ dir }}/render' - '{{ dir }}/graphic' - '{{ dir }}/photo'

When I right-click on a directory and select Create project directory, the subdirectories I need for media projects are added to that directory. It's a simple feature for a desktop, and a little unique to a specific workflow, but it's the feature I want. And thanks to KServices, it's a feature I have. Try out KServices in the KDE Plasma Desktop for yourself, and add the feature you want.

Follow this tutorial to see how I use KService and Ansible on my Linux KDE desktop.

Linux Ansible What to read next This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. Register or Login to post a comment.

How to Enable ChatGPT in ONLYOFFICE Docs on Linux

Tecmint - Wed, 02/15/2023 - 13:58
The post How to Enable ChatGPT in ONLYOFFICE Docs on Linux first appeared on Tecmint: Linux Howtos, Tutorials & Guides .

The rise of AI chatbots and artificial neural networks, which has been taking place over the last few years, definitely makes our life easier in different ways. For example, you can use AI algorithms

The post How to Enable ChatGPT in ONLYOFFICE Docs on Linux first appeared on Tecmint: Linux Howtos, Tutorials & Guides.

Intel Posts Updated CPU Microcode For Two More SGX Vulnerabilities, Privilege Escalation Bug

Phoronix - Wed, 02/15/2023 - 09:12
Patch Tuesday brought AMD disclosing a Ryzen Master security issue on Windows and the Cross-Thread Return Address Predictions bug requiring new handling by Linux's KVM. Over on the Intel side they have disclosed nearly three dozen new issues and as a result also published new Linux CPU microcode files for their recent processors to address the disclosures...

Linux Fix Coming For Recent Stuttering On AMD Ryzen Due To fTPM RNG

Phoronix - Wed, 02/15/2023 - 08:20
Last year AMD issued an advisory around "intermittent system stutter" when engaging the Firmware Trusted Platform Module "fTPM" with newer Ryzen systems running Windows 10 and Windows 11. While at first this only manifested on Windows, with Linux 6.1+ enabling the AMD fTPM RNG by default when present, this system stuttering issue has begun affecting Linux users too...

dav1d 1.1 Released With More AVX-512 Improvements

Phoronix - Wed, 02/15/2023 - 05:00
Yet another prominent open-source software release for Valentine's Day today is... dav1d v1.1! This leading open-source AV1 video decoder is out with its first major update in nearly one year and comes with more AVX-512 tuning as well as more work on Arm NEON optimizations...

Pages