github.com/GoogleContainerTools/skaffold/v2@v2.13.2/docs-v1/content/en/docs/design/api.md (about)

     1  ---
     2  title: "Skaffold API"
     3  linkTitle: "Skaffold API"
     4  weight: 60
     5  
     6  
     7  featureId: api
     8  
     9  ---
    10  When running [`skaffold dev`]({{< relref "/docs/workflows/dev" >}}) or [`skaffold debug`]({{< relref "/docs/workflows/debug" >}}), 
    11  Skaffold starts a server that exposes an API over the lifetime of the Skaffold process.
    12  Besides the CLI, this API is the primary way tools like IDEs integrate with Skaffold for **retrieving information about the
    13  pipeline** and for **controlling the phases in the pipeline**.
    14  
    15  To retrieve information about the Skaffold pipeline, the Skaffold API provides two main functionalities:
    16    
    17    * A [streaming event log]({{< relref "#events-api">}}) created from the different phases in a pipeline run, and
    18    
    19    * A snapshot of the [overall state]({{< relref "#state-api" >}}) of the pipeline at any given time during the run.
    20  
    21  To control the individual phases of the Skaffold, the Skaffold API provides [fine-grained control]({{< relref "#control-api" >}})
    22  over the individual phases of the pipeline (build, deploy, and sync).
    23  
    24  ## Connecting to the Skaffold API
    25  The Skaffold API is `gRPC` based, and it is also exposed via the gRPC gateway as a JSON over HTTP service.
    26  
    27  The API can be enabled via setting the `--rpc-port` or `--rpc-http-port` flags (or both)
    28  depending on whether you want to enable the gRPC API or the HTTP REST API, respectively.
    29  
    30  
    31  {{< alert title="Note">}}
    32  The `--enable-rpc` flag is now deprecated in favor of `--rpc-port` and `--rpc-http-port` flags.
    33  {{</alert>}}
    34  
    35  
    36  For reference, we generate the server's [gRPC service definitions and message protos]({{< relref "/docs/references/api/grpc" >}}) as well as the [Swagger based HTTP API Spec]({{< relref "/docs/references/api/swagger" >}}).
    37  
    38  ## gRPC Server
    39  
    40  The gRPC API can be started by specifying the `--rpc-port` flag. If the specified port is not available, Skaffold will
    41  exit with failure.
    42  
    43  ### HTTP server
    44  
    45  The HTTP REST API can be started by specifying the `--rpc-http-port` flag. If the specified port is not available,
    46  Skaffold will exit with failure.
    47  
    48  Starting the HTTP REST API will also start the gRPC API as it proxies the requests to the gRPC API. By default, Skaffold
    49  chooses a random available port for gRPC, but it can be customized (see below).
    50  
    51  #### Creating a gRPC Client
    52  
    53  To connect to the `gRPC` server at the specified port, create a client using the following code snippet.
    54  
    55  {{< alert title="Note" >}}
    56  The skaffold gRPC server is not compatible with HTTPS, so connections need to be marked as insecure with `grpc.WithInsecure()`
    57  {{</alert>}}
    58  
    59  ```golang
    60  import (
    61    "log"
    62    pb "github.com/GoogleContainerTools/skaffold/proto/v1"
    63    "google.golang.org/grpc"
    64  )
    65  
    66  func main(){
    67    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    68    if err != nil {
    69      log.Fatalf("fail to dial: %v", err)
    70    }
    71    defer conn.Close()
    72    client := pb.NewSkaffoldServiceClient(conn)
    73  }
    74  ```
    75  
    76  
    77  ## API Structure
    78  
    79  Skaffold's API exposes the three main endpoints:
    80  
    81  * Event API - continuous stream of lifecycle events
    82  * State API - retrieve the current state
    83  * Control API - control build/deploy/sync
    84  
    85  ### Event API
    86  
    87  Skaffold provides a continuous development mode, [`skaffold dev`]({{< relref "/docs/workflows/dev" >}}), which rebuilds and redeploys
    88  your application on changes. In a single development loop, one or more container images
    89  may be built and deployed.
    90  
    91  Skaffold exposes events for clients to be notified when phases within a development loop
    92  start, succeed, or fail.
    93  Tools that integrate with Skaffold can use these events to kick off parts of a development workflow depending on them.
    94  
    95  Example scenarios:
    96  
    97  * port-forwarding events are used by Cloud Code to automatically attach debuggers to running containers.     
    98  * using an event indicating a frontend service has been deployed and port-forwarded successfully to
    99  kick off a suite of Selenium tests against the newly deployed service.
   100  
   101  **Event API Contract**
   102  
   103  | protocol | endpoint | encoding |
   104  | ---- | --- | --- |
   105  | HTTP | `http://localhost:{HTTP_RPC_PORT}/v1/events` | newline separated JSON using chunk transfer encoding over HTTP|
   106  | gRPC | `client.Events(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api#skaffoldservice">}}) | protobuf 3 over HTTP |
   107  
   108  
   109  **Examples**
   110  
   111  {{% tabs %}}
   112  {{% tab "HTTP API" %}}
   113  Using `curl` and `HTTP_RPC_PORT=50052`, an example output of a `skaffold dev` execution on our [getting-started example](https://github.com/GoogleContainerTools/skaffold/tree/main/examples/getting-started)
   114  ```bash
   115   curl localhost:50052/v1/events
   116  {"result":{"timestamp":"2019-10-16T18:26:11.385251549Z","event":{"metaEvent":{"entry":"Starting Skaffold: {Version:v0.39.0-16-g5bb7c9e0 ConfigVersion:skaffold/v1 GitVersion: GitCommit:5bb7c9e078e4d522a5ffc42a2f1274fd17d75902 GitTreeState:dirty BuildDate:2019-10-03T15:01:29Z GoVersion:go1.13rc1 Compiler:gc Platform:linux/amd64}"}}}}
   117  {"result":{"timestamp":"2019-10-16T18:26:11.436231589Z","event":{"buildEvent":{"artifact":"gcr.io/k8s-skaffold/skaffold-example","status":"In Progress"}},"entry":"Build started for artifact gcr.io/k8s-skaffold/skaffold-example"}}
   118  {"result":{"timestamp":"2019-10-16T18:26:12.010124246Z","event":{"buildEvent":{"artifact":"gcr.io/k8s-skaffold/skaffold-example","status":"Complete"}},"entry":"Build completed for artifact gcr.io/k8s-skaffold/skaffold-example"}}
   119  {"result":{"timestamp":"2019-10-16T18:26:12.391721823Z","event":{"deployEvent":{"status":"In Progress"}},"entry":"Deploy started"}}
   120  {"result":{"timestamp":"2019-10-16T18:26:12.847239740Z","event":{"deployEvent":{"status":"Complete"}},"entry":"Deploy complete"}}
   121  ..
   122  ```
   123  {{% /tab %}}
   124  {{% tab "gRPC API" %}}
   125  To get events from the API using `gRPC`, first create a [`gRPC` client]({{< relref "#creating-a-grpc-client" >}}).
   126  then, call the `client.Events()` method:
   127  
   128  ```golang
   129  func main() {
   130    ctx, ctxCancel := context.WithCancel(context.Background())
   131    defer ctxCancel()
   132    // `client` is a gRPC client with connection to localhost:50051.
   133    logStream, err := client.Events(ctx, &empty.Empty{})
   134    if err != nil {
   135    	log.Fatalf("could not get events: %v", err)
   136    }
   137    for {
   138    	entry, err := logStream.Recv()
   139    	if err == io.EOF {
   140    		break
   141    	}
   142    	if err != nil {
   143    		log.Fatal(err)
   144    	}
   145    	log.Println(entry)
   146    }
   147  }
   148  ```
   149  {{% /tab %}}
   150  {{% /tabs %}}
   151  
   152  Each [Entry]({{<relref "/docs/references/api/grpc#proto.LogEntry" >}}) in the log contains an [Event]({{< relref "/docs/references/api/grpc#proto.Event" >}}) in the `LogEntry.Event` field and
   153  a string description of the event in `LogEntry.entry` field.
   154  
   155  
   156  ### State API
   157  
   158  The State API provides a snapshot of the current state of the following components:
   159  
   160  - build state per artifacts 
   161  - deploy state
   162  - file sync state 
   163  - status check state per resource 
   164  - port-forwarded resources
   165  
   166  **State API Contract**  
   167  
   168  | protocol | endpoint | encoding |
   169  | ---- | --- | --- |
   170  | HTTP | `http://localhost:{HTTP_RPC_PORT}/v1/state` | newline separated JSON using chunk transfer encoding over HTTP|  
   171  | gRPC | `client.GetState(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api/grpc#skaffoldservice">}}) | protobuf 3 over HTTP |
   172  
   173  
   174  **Examples** 
   175  {{% tabs %}}
   176  {{% tab "HTTP API" %}}
   177  Using `curl` and `HTTP_RPC_PORT=50052`, an example output of a `skaffold dev` execution on our [microservices example](https://github.com/GoogleContainerTools/skaffold/tree/main/examples/microservices)
   178  ```bash
   179   curl localhost:50052/v1/state | jq
   180   {
   181     "buildState": {
   182       "artifacts": {
   183         "gcr.io/k8s-skaffold/leeroy-app": "Complete",
   184         "gcr.io/k8s-skaffold/leeroy-web": "Complete"
   185       }
   186     },
   187     "deployState": {
   188       "status": "Complete"
   189     },
   190     "forwardedPorts": {
   191       "9000": {
   192         "localPort": 9000,
   193         "remotePort": 8080,
   194         "namespace": "default",
   195         "resourceType": "deployment",
   196         "resourceName": "leeroy-web"
   197       },
   198       "50055": {
   199         "localPort": 50055,
   200         "remotePort": 50051,
   201         "namespace": "default",
   202         "resourceType": "service",
   203         "resourceName": "leeroy-app"
   204       }
   205     },
   206     "statusCheckState": {
   207       "status": "Succeeded"
   208     },
   209     "fileSyncState": {
   210       "status": "Not Started"
   211     }
   212   }
   213  ```
   214  {{% /tab %}}
   215  {{% tab "gRPC API" %}}
   216  To retrieve the state from the server using `gRPC`, first create [`gRPC` client]({{< relref "#creating-a-grpc-client" >}}).
   217  Then, call the `client.GetState()` method:
   218  
   219  ```golang
   220  func main() {
   221    // Create a gRPC client connection to localhost:50051.
   222    // See code above
   223    ctx, ctxCancel := context.WithCancel(context.Background())
   224    defer ctxCancel()
   225    grpcState, err = client.GetState(ctx, &empty.Empty{})
   226    ...
   227  }
   228  ```
   229  {{% /tab %}}
   230  {{% /tabs %}}
   231  
   232  ### Control API
   233  
   234  By default, [`skaffold dev`]({{< relref "/docs/workflows/dev" >}}) will automatically build artifacts, deploy manifests and sync files on every source code change.
   235  However, this behavior can be paused and individual actions can be gated off by user input through the Control API.
   236  
   237  With this API, users can tell Skaffold to wait for user input before performing any of these actions,
   238  even if the requisite files were changed on the filesystem. By doing so, users can "queue up" changes while
   239  they are iterating locally, and then have Skaffold rebuild and redeploy only when asked. This can be very
   240  useful when builds are happening more frequently than desired, when builds or deploys take a long time or
   241  are otherwise very costly, or when users want to integrate other tools with `skaffold dev`.
   242  
   243  The automation can be turned off or on using the Control API, or with `auto-build` flag for building, `auto-deploy` flag for deploys, and the `auto-sync` flag for file sync.
   244  If automation is turned off for a phase, Skaffold will wait for a request to the Control API before executing the associated action.
   245  
   246  Each time a request is sent to the Control API by the user, the specified actions in the payload are executed immediately.
   247  This means that _even if there are new file changes_, Skaffold will wait for another user request before executing any of the given actions again.
   248  
   249  **Control API Contract**
   250  
   251  | protocol | endpoint | 
   252  | --- | --- |
   253  | HTTP, method: POST | `http://localhost:{HTTP_RPC_PORT}/v1/execute`, the [Execution Service]({{<relref "/docs/references/api/swagger#/SkaffoldService/Execute">}}) |
   254  | gRPC | `client.Execute(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api/grpc#skaffoldservice">}}) |
   255  | HTTP, method: PUT | `http://localhost:{HTTP_RPC_PORT}/v1/build/auto_execute`, the [Auto Build Service]({{<relref "/docs/references/api/swagger#/SkaffoldService/AutoBuild">}}) |
   256  | gRPC | `client.AutoBuild(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api/grpc#skaffoldservice">}}) |
   257  | HTTP, method: PUT | `http://localhost:{HTTP_RPC_PORT}/v1/sync/auto_execute`, the [Auto Sync Service]({{<relref "/docs/references/api/swagger#/SkaffoldService/AutoSync">}}) |
   258  | gRPC | `client.AutoSync(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api/grpc#skaffoldservice">}}) |
   259  | HTTP, method: PUT | `http://localhost:{HTTP_RPC_PORT}/v1/deploy/auto_execute`, the [Auto Deploy Service]({{<relref "/docs/references/api/swagger#/SkaffoldService/AutoDeploy">}}) |
   260  | gRPC | `client.AutoDeploy(ctx)` method on the [`SkaffoldService`]({{< relref "/docs/references/api/grpc#skaffoldservice">}}) |
   261  
   262  
   263  **Examples**
   264  
   265  {{% tabs %}}
   266  {{% tab "HTTP API" %}}
   267  
   268  Using our [Quickstart example]({{< relref "/docs/quickstart" >}}), we can start skaffold with `skaffold dev --auto-build=false`.
   269  When we change `main.go`, Skaffold will notice file changes but will not rebuild the image until it receives a request to the Control API with `{"build": true}`:
   270  
   271  ```bash
   272  curl -X POST http://localhost:50052/v1/execute -d '{"build": true}'
   273  ```       
   274  
   275  At this point, Skaffold will wait to deploy the newly built image until we invoke the Control API with `{"deploy": true}`:
   276   
   277  ```bash
   278  curl -X POST http://localhost:50052/v1/execute -d '{"deploy": true}'
   279  ```       
   280  
   281  These steps can also be combined into a single request:
   282  
   283  ```bash
   284  curl -X POST http://localhost:50052/v1/execute -d '{"build": true, "deploy": true}'
   285  ``` 
   286  
   287  We can make Skaffold start noticing file changes automatically again by issuing the requests:
   288  
   289  ```bash
   290  curl -X PUT http://localhost:50052/v1/build/auto_execute -d '{"enabled": true}'
   291  curl -X PUT http://localhost:50052/v1/deploy/auto_execute -d '{"enabled": true}'
   292  ``` 
   293  
   294  {{% /tab %}}
   295  {{% tab "gRPC API" %}}
   296  To access the Control API via the `gRPC`, create [`gRPC` client]({{< relref "#creating-a-grpc-client" >}}) as before.
   297  Then, use the `client.Execute()` method with the desired payload to trigger it once:
   298  
   299  ```golang
   300  func main() {
   301      ctx, ctxCancel := context.WithCancel(context.Background())
   302      defer ctxCancel()
   303      // `client` is the gRPC client with connection to localhost:50051.
   304      _, err = client.Execute(ctx, &pb.UserIntentRequest{
   305          Intent: &pb.Intent{
   306              Build:  true,
   307              Sync:   true,
   308              Deploy: true,
   309          },
   310      })
   311      if err != nil {
   312          log.Fatalf("error when trying to execute phases: %v", err)
   313      }
   314  }
   315  ```
   316  Use the `client.AutoBuild()`,`client.AutoSync()` and `client.AutoDeploy()` method to enable or disable auto build, auto sync and auto deploy:
   317  
   318  ```golang
   319  func main() {
   320      ctx, ctxCancel := context.WithCancel(context.Background())
   321      defer ctxCancel()
   322      // `client` is the gRPC client with connection to localhost:50051.
   323      _, err = client.AutoBuild(ctx, &pb.TriggerRequest{
   324  		State: &pb.TriggerState{
   325  			Val: &pb.TriggerState_Enabled{
   326  				Enabled: true,
   327  			},
   328  		},
   329  	})    if err != nil {
   330          log.Fatalf("error when trying to auto trigger phases: %v", err)
   331      }
   332  }
   333  ```
   334  {{% /tab %}}
   335  {{% /tabs %}}