Yocto: overriding kernel configuration - linux-kernel

Related to this question.
In order to customize the kernel configuration I created in my custom layer this structure:
$ tree recipes-kernel/
recipes-kernel/
└── linux
├── files
│   └── <image>-defconfig
└── linux-stm32mp_4.19.bbappend
Where the defconfig file is actually the .config used to manually compile the kernel (see the other question). The bbappend file contains the following code:
SRC_URI += "file://<full-path>/meta-custom-layer/recipes-kernel/linux/files/<image>-defconfig"
KERNEL_DEFCONFIG_stm32mp1_<variant> = "{WORKDIR}/<image>-defconfig"
I'm sure the file is processed because if I change the name of the defconfig bitbake raises a file not found error.
The problem is the compiled kernel does not have my customization.
But if I copy my defconfig to the build directory (i.e. tmp/work/stm32mp1_<variant>-openstlinux_eglfs-linux-gnueabi/linux-stm32mp/4.19-r0/linux-stm32mp1-<variant>-standard-build/.config) and manually bitbake virtual/kernel) it does.
So it seems it searches and finds my defconfig but then it ignores it.
Where is my mistake?

I don't know what is your mistake. But I know what I do.
Instead of trying to overload defconfig I let bitbake generate kernel fragments (diffs from the kernel supplied defconfig): https://edison-fw.github.io/meta-intel-edison/5.1-Bitbake-tricks#configuring-the-kernel-and-grab-the-kernel-fragment
Then I add the fragments to my recipe: https://github.com/edison-fw/meta-intel-edison/blob/warrior/meta-intel-edison-bsp/recipes-kernel/linux/linux-yocto_5.4.0.bb

Related

Bitbake not finding files specified in SRC_URI when changing directory name

I'm writing a recipe that copies some configuration files over to my image (like a cramfs.conf that goes into /etc/modprobe.d to disable cramfs). Here is the structure of my recipe directory:
.
├── compliance-config.bb
└── configs
└── fs
├── 1-1-1-1-cramfs.conf
├── 1-1-1-2-freevxfs.conf
...
In my recipe I do the following:
SRC_URI += "file://fs"
do_install() {
install -d ${D}${sysconfdir}/modprobe.d/
install -m 0644 ${WORKDIR}/fs/*.conf ${D}${sysconfdir}/modprobe.d/
}
This works, but when I change the folder name of fs to something more descriptive (and of course accordingly change the SRC_URI and path in do_install()), it doesn't find the files anymore and gives me (Edit: to clarify, this error happens when I change the directory name from fs to fsconfigs for example, tried different names to make sure I don't accidentally name it in a forbidden way, names like abctest also don't work).
ERROR: compliance-config-1.0-r0 do_fetch: Fetcher failure: Unable to find file file://fsconfigs anywhere. The paths that were searched were:
[...long list of paths...]
So I thought I needed to do a clean build, but running bitbake -c clean <image> or bitbake -fc cleanall <image> beforehand doesn't help.
Why does bitbake not find my files if I change the specified directory?
This is a better :
.
├── compliance-config.bb
└── files
├── 1-1-1-1-cramfs.conf
├── 1-1-1-2-freevxfs.conf
Then add SRC_URI += "file://fsconfigs" for instance.
You should know that the default FILESPATH variable is the default set of directories the OpenEmbedded build system uses when searching for patches and files.
The default value for the FILESPATH variable is defined in the base.bbclass as follow :
FILESPATH = "${#base_set_filespath(["${FILE_DIRNAME}/${BP}", \
"${FILE_DIRNAME}/${BPN}", "${FILE_DIRNAME}/files"], d)}"
Here ${BP} stand for the base recipe name and your Package Version: ${BPN}-${PV}
If you want the build system to look in directories other than the defaults, the best practiec is to extend the FILESPATH variable by using the FILESEXTRAPATHS variable.
Note that SRC_URI is used to specify files, not directories.
https://docs.yoctoproject.org/ref-manual/variables.html?highlight=filesextrapaths

protoc Go Package Command Local Overwrite?

Following the Quick Start gRPC Go guide on the official gRPC website it has a step which asks the user to recompile the updated .proto file using this command:
$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld/helloworld.proto
I'm a little confused as to how the newly compiled protobuf files are consumed by the "human written" Go code.
In the example "human written" Go code they reference the protobuf code using the following import:
pb "google.golang.org/grpc/examples/helloworld/helloworld"
protoc does not update this package but instead updates the helloworld/helloworld.proto in the same directory that the command is run in. How does the protoc command ensure that the "human written" Go code consumes the newly compiled protobuf code?
I find this one of the more confusing aspects of Protobufs (and gRPC).
I think the issue being solved is that Protobufs need to:
Permit namespacing to scope services|messages to e.g. DNS domains
Support a myriad programming languages (which implement namespacing differently).
protochas options that permit (re)mapping of e.g. a protobuf's package v1/api to a language-specific namespace using protobuf options, e.g. go_package). See Go Generated Code for Golang.
This is slightly more complex when using Go Modules but, in summary, what you're experiencing is probably some (unexpected) combination of the above where, the sample code assumes one module name and protoc is building on the assumption of a different one.
TL;DR update the code's module reference to reflect the correctly generated pb path. If the generate code is in the wrong place, you can simply move it to the correct subdirectory (path) but it's better to update your protoc command to generate the files to the correct directory.
Example
something.proto:
syntax = "proto3";
package v1alpha1;
option go_package = "github.com/me/my-protos;v1alpha1";
NOTE go_package aliases the proto package v1alpha1 to what I want to reference as github.com/me/my-protos in Golang.
Then I generate with:
MODULE="github.com/me/my-protos"
protoc \
--proto_path=. \
--go_out=./api/v1alpha1 \
--go_opt=module=${MODULE} \
--go-grpc_out=./api/v1alpha1 \
--go-grpc_opt=module=${MODULE} \
./something.proto
NOTE This example generate gRPC code too. It avoids (!) protoc creating a path github.com/me/my-protos for the generated code because I'm generating the source in that repo. I just want the relative path ./api/v1alpha where the files will be created.
Which yields:
my-protos
├── something.proto
├── api
│   └── v1alpha1
│   ├── something_grpc.pb.go
│   └── something.pb.go
├── go.mod
├── go.sum
└── README.md
And I can import with:
import (
pb "github.com/me/my-protos/api/v1alpha1"
)
NOTE From a different repo, I can now access my protos repo github.com/me/my-project/api/v1alpha1 combining the repro and the generated location to give my desired path.

How do I run ansible-test on the root of my collection?

I'm currently developing my own Ansible collection and following the documentation. The directory structure looks like this:
~/.ansible/collections/gertvdijk/mycollection
├── galaxy.yml
├── plugins
│   └── lookup
│   └── mylookup.py
├── README.md
└── tests
└── unit
└── plugins
└── lookup
└── test_mylookup.py
The location ~/.ansible/collections/gertvdijk/mycollection is chosen for convenience so that it's found on the default search paths for collections (COLLECTIONS_PATHS).
The Ansible developer document section Testing collections mentions that I should use ansible-test command from the root of my collection with the given structure.
You must always execute ansible-test from the root directory of a collection.
However, that fails to me, with an error as if I should use this in a project already.
Even running --help fails with the current working directory error:
$ ansible-test --help
ERROR: The current working directory must be at or below:
- an Ansible collection: {...}/ansible_collections/{namespace}/{collection}/
Current working directory: /home/gert/.ansible/collections/gertvdijk/mycollection
Same thing happens by cloning an existing community collection (e.g. community.grafana). The GitHub CI steps include an installation in a ansible_collections/{namespace}/{collection} path (seen here).
Taking that as a work-around for now (I'd like to avoid that); move the repository of the collection to some path that includes /ansible_collections/gertvdijk/mycollection and then run it from there.
This can't be true, right, that the directory name two levels up make or break the ansible-test tool? What am I missing here?
TL;DR: The path for your home collection should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection
The directories listed in COLLECTION_PATH are actually expected to contain a top level ansible_collections folder. This is linked to the ansible_collections convention used by e.g. module_utils as explained in the documentation
You can also observe how a blank folder gets structured by running e.g.
ansible-galaxy collection install -p /whatever community.grafana
In this case, you will end up with the folder /whatever/ansible_collections/community/grafana.
So your actual home folder collection path should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection

How to handle paths for supporting files in a package in Go?

Go program with the following structure:-
├── app.go
├── bin
│   └── run.go
├── config
│   └── Config.go
└── package1
   ├── package1_file.go
   └── tmpl
   └── template.tmpl
Now, in package1_file.go, I've accessed template.tmpl via relative path like:
t, err := template.ParseFiles("./tmpl/template.tmpl")
When I run tests, tests are able to run successfully because my guess is, Go changes the current working directory when running tests for packages. go tests -v ./...
However, when I run (go build -o app && ./app) the program from the root folder, I get error complaining that file doesn't exist.
Error compiling template: open ./tmpl/template.tmpl: no such file or directory
It starts working when I change the path to package2/tmpl/template.tmpl.
The code outside package2 has nothing to do with this template file so I don't want to expose it as a parameter to a function while exposing package2. What are my options?
What is the right way to target support files like these?
You're operating under some mistaken assumptions here - primarily that the project source code or directory structure are in any way relevant at runtime. They aren't.
A Go program compiles to a single binary file that can be executed anywhere, without the source, without Go installed - just the binary. You need to consider that any time you have any kind of files in your project that you will need at runtime:
You need to decide how these files will be located:
You can mandate a path, either relative to CWD at time of execution, or absolute (but you shouldn't)
You can accept the path as a runtime parameter, by CLI, environment variable, config file, etc.
You can embed them into the binary itself using one of the many packages available (seriously - so many that a Google search for go embed static files turns up not only several libraries, but several articles comparing various libraries)
You need to decide how the whole thing will be packaged:
You could zip/tar/whatever the resources alongside the binary
You could zip/tar/whatever the resources and binary all together
As above, you could embed them into the binary as a single file
There are some choices you'll have to make as to how you want to handle this but the key takeaway is don't assume the path in your source code will be at all relevant at runtime. Parameterize at least the root path to the resources so that your code will work wherever they may be, and then your tests can pass in an appropriate path to use for testing.
You can use os.Getwd() to get the path to the root working dir. Then, concat the rest of the path to your template dir. In your case:
wd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
t, err := template.ParseFiles(wd + "/package1/tmpl/template.tmpl")

Structuring a multi-executable Go project

I am trying to build a micro-services architecture project in Go. I am currently using Go 1.11 which supports modules, so I put my root directory in an arbitrary chosen directory, outside of GOPATH.
If I am getting the micro-services architecture concepts right, although my microservices need to be independent, they can share dependencies (and I don't see another way to do stuff, is it?)
Below is my directory structure:
.
├── go.mod
├── lambda
│   └── account_create
│   └── main.go
├── readme.md
└── types
├── account.go
├── location.go
├── order.go
├── pricing.go
├── product.go
└── types.go
Now the behavior I expected was to be able to run go build lambda/account_create and get an executable with that functionality so I can supply it to the respective AWS Lambda function.
However, when I run the command, I get:
can't load package: package lambda/account_create: unknown import path "lambda/account_create": cannot find module providing package lambda/account_create
Please explain me why this does not work and give me some advice on how a project like this should look.
Thank you very much!
Edit Here is my lambda/account_create/main.go file contents:
package account_create
import (
"fmt"
"roasted.ro/pkg/types"
)
func main() {
account := types.UserAccount{Name: "Victor"}
fmt.Printf("Welcome %s", account.Name)
}
To answer the latter part of your question (as the first half is more about preference), you need to do:
go build ./lambda/account_create
Notice the ./. go build takes in a package name or a path. If you don't prepend the path with a ./, it assumes you are giving it a package name.
Edit: the package has to be main if you want an executable. According to the docs, you always have to use package main for projects that build an executable:
Executable commands must always use package main.
Edit: I'll add some opinions on layout:
Consider which parts of your project are exported to other go projects. Meaning someone could import your package and expect to gain value and not have their code break when yours changes.
That should be either in a github.com/you/pkg/somepath package or just github.com/you/somepath.
Anything else (other than main packages) should be under a /internal package.
I typically make a /cmd/myexecurable1 /cmd/myexecurable2 and so forth for each executable.

Resources