github.com/inspektor-gadget/inspektor-gadget@v0.28.1/docs/devel/ci.md (about) 1 --- 2 title: Continuous Integration 3 weight: 210 4 description: > 5 Inspektor Gadget continuous integration workflow 6 --- 7 8 This repository uses GitHub Actions to create a custom Continuous Integration 9 (CI) workflow named `Inspektor Gadget CI`. This workflow compiles and uploads 10 the Inspektor Gadget CLI (`kubectl-gadget` and `ig`) and gadget container 11 images and runs their unit and integration tests. In addition, it verifies 12 that the documentation is up-to-date and runs a static code analysis using 13 Golang linters. 14 15 A fork of this project should enable GitHub Actions in the repo settings page 16 and add the proper 17 [secrets](https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets-for-a-repository) 18 to be able to use this workflow. The following sections describes what 19 secrets need to be added to enable all the CI tests. 20 21 ## Container repository 22 23 To run the integration tests, it is necessary to have the gadget container image 24 available so that it can be installed/loaded in the Kubernetes cluster where the 25 tests will run. 26 27 As a default, images are shared via artifacts between workflow jobs 28 for all CI pipeline. When the target branch correspond to the main or 29 the push refers to a tag, the images are also pushed to 30 `ghcr.io/${{ github.repository }}`. This permits a clear separation 31 between "in development" images and production ones. 32 33 Note that, you need to [set repository packages as public](https://docs.github.com/en/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#configuring-visibility-of-container-images-for-your-personal-account) to allow anonymous pull. 34 35 ## Run integration tests on ARO 36 37 Optionally, we can add the secrets described in this section so that the 38 integration tests will also run on a pre-created [Azure Red Hat OpenShift 39 (ARO)](https://docs.microsoft.com/en-us/azure/openshift/intro-openshift) 40 cluster. Consider that the Inspektor Gadget workflow will still success even if 41 no ARO cluster is provided through these secrets. 42 43 ### Create a cluster 44 45 These are the steps to create an ARO cluster using the [Azure 46 CLI](https://docs.microsoft.com/en-us/cli/azure/): 47 48 ```bash 49 $ export SUBSCRIPTION=<mySubscription> 50 $ export RESOURCEGROUP=<myResourceName> 51 $ export LOCATION=<myLocation> 52 $ export CLUSTER=<myCluster> 53 $ export VNET=<myVNET> 54 $ export MASTSUB=<myMASTSUB> 55 $ export WORKSUB=<myWORKSUB> 56 57 # Set subscription so that we don't need to specify it at every command 58 $ az account set --subscription $SUBSCRIPTION 59 60 # Register resource providers 61 $ az provider register -n Microsoft.RedHatOpenShift --wait 62 $ az provider register -n Microsoft.Compute --wait 63 $ az provider register -n Microsoft.Storage --wait 64 $ az provider register -n Microsoft.Authorization --wait 65 66 # Create resource group 67 $ az group create --name $RESOURCEGROUP --location $LOCATION 68 69 # Create virtual network and two empty subnets for the master and the worker nodes. 70 $ az network vnet create --resource-group $RESOURCEGROUP --name $VNET --address-prefixes 10.0.0.0/22 71 $ az network vnet subnet create --resource-group $RESOURCEGROUP --vnet-name $VNET --name $MASTSUB --address-prefixes 10.0.0.0/23 --service-endpoints Microsoft.ContainerRegistry 72 $ az network vnet subnet create --resource-group $RESOURCEGROUP --vnet-name $VNET --name $WORKSUB --address-prefixes 10.0.2.0/23 --service-endpoints Microsoft.ContainerRegistry 73 $ az network vnet subnet update --name $MASTSUB --resource-group $RESOURCEGROUP --vnet-name $VNET --disable-private-link-service-network-policies true 74 75 # Create the cluster (Minimum 3 worker nodes must be used) 76 $ az aro create --resource-group $RESOURCEGROUP --name $CLUSTER --vnet $VNET --master-subnet $MASTSUB --worker-count 3 --worker-subnet $WORKSUB 77 ``` 78 79 Considerations: 80 - After executing the `az aro create` command, it normally takes about 35 81 minutes to create a cluster. 82 - For the sake of simplicity, we are not providing a [Red Hat pull 83 secret](https://docs.microsoft.com/en-us/azure/openshift/tutorial-create-cluster#get-a-red-hat-pull-secret-optional) 84 during the cluster creation, so our cluster will not include samples or 85 operators from Red Hat or certified partners. However, it is not a requirement 86 to run the Inspektor Gadget integration tests on it. 87 - Creating an ARO cluster requires specific permissions, check [the 88 documentation](https://docs.microsoft.com/en-us/azure/openshift/tutorial-create-cluster#verify-your-permissions) 89 to be sure you have them. 90 91 ### Delete a cluster 92 93 If we need to delete our cluster, it is enough to execute: 94 ```bash 95 $ az group delete --name $RESOURCEGROUP 96 ``` 97 98 Take into account that it will remove the entire resource group and all 99 resources inside it. 100 101 Further details about creating an ARO cluster can be found in the [Azure Red Hat 102 OpenShift 103 documentation](https://docs.microsoft.com/en-us/azure/openshift/tutorial-create-cluster). 104 105 ### Connect to a cluster 106 107 Fist of all, to be able to connect to our cluster, we need the following 108 information: 109 110 ```bash 111 # API Server URL 112 $ az aro show --subscription $SUBSCRIPTION -g $RESOURCEGROUP -n $CLUSTER --query apiserverProfile.url 113 https://api.server.example.io:1234 114 115 # Credentials 116 $ az aro list-credentials --subscription $SUBSCRIPTION -g $RESOURCEGROUP -n $CLUSTER 117 { 118 "kubeadminPassword": "myPassword", 119 "kubeadminUsername": "myUsername" 120 } 121 ``` 122 123 #### From GitHub actions 124 125 The `test-integration` job is already configured to authenticate and set the 126 kubeconf context to the ARO cluster configured in the GitHub repository. So all 127 we need to do is to add the following actions secrets: 128 129 - `OPENSHIFT_SERVER`: The API server URL: `https://api.server.example.io:1234`. 130 - `OPENSHIFT_USER`: The `kubeadminUsername` from the JSON output of the 131 `list-credentials` command. 132 - `OPENSHIFT_PASSWORD`: The `kubeadminPassword` from the JSON output of the 133 `list-credentials` command. 134 135 Further details about connect to an ARO cluster from GitHub actions can be found 136 in the [Azure Red Hat OpenShift 137 documentation](https://docs.microsoft.com/en-us/azure/openshift/tutorial-connect-cluster#connect-using-the-openshift-cli) 138 and the [redhat-actions/oc-login 139 documentation](https://github.com/redhat-actions/oc-login). 140 141 #### From a host 142 143 For debugging, it might be necessary to connect to the cluster from a host. We 144 can do it by using the `oc` tool: 145 146 ```bash 147 $ oc login $apiServer -u $kubeadminUsername -p $kubeadminPassword 148 ``` 149 150 Notice that it configures the kubectl configuration with a new context. 151 152 Please take into account that any change done on this cluster could cause issues 153 with the integration tests running on GitHub actions at that moment. 154 155 156 ## Run integration tests on AKS 157 158 When secrets described in the below sections are set, the integration tests 159 will also run on 160 [AKS clusters](https://docs.microsoft.com/en-us/azure/aks/intro-kubernetes). 161 162 ### Create the clusters 163 164 As Inspektor Gadget support both `amd64` and `arm64`, two clusters will be 165 created when the CI is triggered. 166 To be able to create them in the CI, you need to follow [these instructions](https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-cli%2Clinux): 167 168 ```bash 169 $ subscription_id=<mySubscriptionID> 170 $ resourcegroup=<myResourceName> 171 $ location=<myLocation> 172 $ app_name=<myAppName> 173 # federated_name should not have spaces! 174 $ federated_name=<myFederatedCredentialName> 175 $ organization=<myGitHubOrganization> 176 $ repository=<myGitHubRepository> 177 $ environment=<myCIJobEnvironment> 178 179 # Set subscription so that we don't need to specify it at every command. 180 $ az account set --subscription $subscription_id 181 182 # Create resource group. 183 # This is not needed to generate secrets but it is mandatory to creates AKS 184 # cluster in the CI. 185 $ az group create --name $resourcegroup --location $location 186 187 # Register an application for your CI. 188 $ az ad app create --display-name $app_name 189 { 190 # It should reply with a big JSON object. 191 } 192 193 # Let's get the ID of the created application 194 $ app_id=$(az ad app list --display-name $app_name --query [0].id | tr -d '"') 195 196 # Let's create a service principal for the corresponding application. 197 $ az ad sp create --id $app_id 198 { 199 # It should reply with a big JSON object. 200 } 201 202 # We now want to get the service principal ID. 203 $ sp_id=$(az ad sp list --display-name $app_name --query [0].id | tr -d '"') 204 205 # Let's create a new role for this service principal. 206 $ az role assignment create --role contributor --assignee-object-id $sp_id --assignee-principal-type ServicePrincipal --scope /subscriptions/$subscription_id/resourceGroups/$resourcegroup 207 { 208 # It should reply with a big JSON object. 209 } 210 211 # Create the federated credential to be able to "az login" from the CI. 212 $ az ad app federated-credential create --id $app_id --parameters <(echo "{ 213 \"name\": \"${federated_name}\", 214 \"issuer\": \"https://token.actions.githubusercontent.com\", 215 \"subject\": \"repo:${organization}/${repository}:environment:${environment}\", 216 \"description\": \"AKS federated credentials for CI\", 217 \"audiences\": [ 218 \"api://AzureADTokenExchange\" 219 ] 220 }") 221 { 222 # It replies with a JSON object which has name set to $federated_name. 223 } 224 ``` 225 226 After doing this, you will need to create several secrets: 227 228 1. `AZURE_AKS_CLIENT_ID`: The application ID as given by `az ad app list --display-name $app_name --query [0].appId`. 229 1. `AZURE_AKS_TENANT_ID`: The tenant ID as given by `az account show --query tenantId`. 230 1. `AZURE_AKS_SUBSCRIPTION_ID`: The subscription used to create the federated 231 credentials as given by `az account show --query id`. 232 1. `AZURE_AKS_RESOURCE_GROUP`: It stores the name of the resource group where 233 the clusters will be created. 234 235 The workflow will create the `amd64` and `arm64` clusters for you by using the 236 above information. 237 By default, each of this cluster features 238 [3 nodes](https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-create). 239 Once created, the integration tests will be run on these clusters. 240 Finally, the clusters are deleted, whatsoever is the result of the tests. 241 242 ## Run integration tests on EKS 243 244 We use OpenID Connect to authenticate GitHub Actions against AWS. If you want to run the integration 245 tests on your fork, follow 246 [this](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services) 247 to configure your AWS account. 248 249 You need to create a role with the [minimum IAM 250 policies](https://eksctl.io/usage/minimum-iam-policies/) needed by eksctl. Save the name of this 251 role (including the rull `arn:aws..` prefix). in a [repository 252 variable](https://docs.github.com/en/actions/learn-github-actions/variables#creating-configuration-variables-for-a-repository) 253 named `AWS_ROLE`. 254 255 ## Run integration tests on GKE 256 257 In order to run the integration tests on GKE on a fork, you need to set the following secrets: 258 259 - `GKE_PROJECT`: The GCP project where the GKE cluster is located. 260 - `GKE_SERVICE_ACCOUNT`: The service account used to authenticate to GCP. 261 - `GKE_WORKLOAD_IDENTITY_PROVIDER`: The workload identity provider used to authenticate to GCP. 262 263 these secrets use OpenID Connect to authenticate GitHub Actions against GCP for more information on how it works 264 you can check the GitHub documentation [here](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform#adding-a-google-cloud-workload-identity-provider). 265 The steps to create a service account and a workload identity provider can be found in the [google-github-actions/auth](https://github.com/google-github-actions/auth?tab=readme-ov-file#workload-identity-federation-through-a-service-account) repository till step 6. 266 In terms of permissions, the service account needs to have the following roles: 267 268 - `roles/container.admin` 269 - `roles/container.clusterAdmin` 270 - `roles/iam.serviceAccountUser` 271 272 You can see the guide [here](https://cloud.google.com/kubernetes-engine/docs/how-to/iam#assigning_roles_to_service_accounts) to see how these roles can be assigned to the service account. 273 274 ## Benchmarks 275 276 Inspektor Gadget has 277 [benchmark tests](https://github.com/inspektor-gadget/inspektor-gadget/blob/main/internal/benchmarks/benchmarks_test.go) 278 that are automatically executed and published by 279 [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark). You can see the results on: 280 281 https://inspektor-gadget.github.io/ig-benchmarks/dev/bench/index.html 282 283 This requires a GitHub API token (secret `BENCHMARKS_TOKEN`) configured with read and write access to two repositories: 284 - [inspektor-gadget/inspektor-gadget](https://github.com/inspektor-gadget/inspektor-gadget): required to allow the bot to post comments 285 - [inspektor-gadget/ig-benchmarks](https://github.com/inspektor-gadget/ig-benchmarks/tree/gh-pages), see the `gh-pages` branch. 286 287 The GitHub Action is disabled for pushes on forks or PR from forks, so the result page will not be updated by forks. 288 In this way, forks can still use other parts of the CI without failing, even without the `BENCHMARKS_TOKEN` secret. 289 290 ## Sign release artifact 291 292 We compute hash sum of all our release artifacts and the file containing these checksums is signed using [`cosign`](https://github.com/sigstore/cosign). 293 To sign this file, you will need to create a private key with an associated password: 294 295 ```bash 296 $ cosign generate-key-pair 297 Enter password for private key: 298 Enter password for private key again: 299 Private key written to cosign.key 300 Public key written to cosign.pub 301 ``` 302 303 You will then need to store the content of `cosign.key` in the `COSIGN_PRIVATE_KEY` and the password you used to create the key in `COSIGN_PASSWORD`. 304 Without these secrets, the release job will not be run.