From 7349d088a9c93e534d70d45a83bf4c02309f1a62 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:13:30 -0400 Subject: [PATCH 01/23] add new deployment/statefuleset templates --- .../bitcoind-chain-coordinator.template.yaml | 113 ++++++++++++++++++ .../stacks-blockchain.template.yaml | 69 +++++++++++ .../stacks-blockchain-api.template.yaml | 86 +++++++++++++ 3 files changed, 268 insertions(+) create mode 100644 templates/deployments/bitcoind-chain-coordinator.template.yaml create mode 100644 templates/deployments/stacks-blockchain.template.yaml create mode 100644 templates/stateful-sets/stacks-blockchain-api.template.yaml diff --git a/templates/deployments/bitcoind-chain-coordinator.template.yaml b/templates/deployments/bitcoind-chain-coordinator.template.yaml new file mode 100644 index 0000000..a49d7e4 --- /dev/null +++ b/templates/deployments/bitcoind-chain-coordinator.template.yaml @@ -0,0 +1,113 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: bitcoind-chain-coordinator + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: bitcoind-chain-coordinator + name: bitcoind-chain-coordinator + namespace: "{namespace}" +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: bitcoind-chain-coordinator + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: bitcoind-chain-coordinator + template: + metadata: + labels: + app.kubernetes.io/component: bitcoind-chain-coordinator + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: bitcoind-chain-coordinator + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-preemptible + operator: DoesNotExist + containers: + - command: + - /usr/local/bin/bitcoind + - -conf=/etc/bitcoin/bitcoin.conf + - -nodebuglogfile + - -pid=/run/bitcoind.pid + image: quay.io/hirosystems/bitcoind:devnet-v3 + imagePullPolicy: IfNotPresent + name: bitcoind + ports: + - containerPort: 18444 + name: p2p + protocol: TCP + - containerPort: 18443 + name: rpc + protocol: TCP + volumeMounts: + - mountPath: /etc/bitcoin + name: bitcoind + readOnly: true + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + memory: 256Mi + - command: + - ./stacks-network + - --namespace=$(NAMESPACE) + - --manifest-path=/etc/stacks-network/project/Clarinet.toml + - --network-manifest-path=/etc/stacks-network/project/settings/Devnet.toml + - --deployment-plan-path=/etc/stacks-network/project/deployments/default.devnet-plan.yaml + - --project-root-path=/etc/stacks-network/project/ + env: + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + image: stacks-network-orchestrator + imagePullPolicy: Never + name: chain-coordinator + ports: + - containerPort: 20445 + name: coordinator-in + protocol: TCP + - containerPort: 20446 + name: coordinator-con + protocol: TCP + volumeMounts: + - mountPath: /etc/stacks-network/project + name: project-manifest + - mountPath: /etc/stacks-network/project/settings + name: devnet + - mountPath: /etc/stacks-network/project/deployments + name: deployment-plan + - mountPath: /etc/stacks-network/project/contracts + name: project-dir + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + memory: 256Mi + volumes: + - configMap: + name: bitcoind + name: bitcoind + - configMap: + name: project-manifest + name: project-manifest + - configMap: + name: devnet + name: devnet + - configMap: + name: deployment-plan + name: deployment-plan + - configMap: + name: project-dir + name: project-dir \ No newline at end of file diff --git a/templates/deployments/stacks-blockchain.template.yaml b/templates/deployments/stacks-blockchain.template.yaml new file mode 100644 index 0000000..813fc94 --- /dev/null +++ b/templates/deployments/stacks-blockchain.template.yaml @@ -0,0 +1,69 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: stacks-blockchain + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain + name: stacks-blockchain + namespace: "{namespace}" +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: stacks-blockchain + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain + template: + metadata: + labels: + app.kubernetes.io/component: stacks-blockchain + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-preemptible + operator: DoesNotExist + containers: + - command: + - stacks-node + - start + - --config=/src/stacks-blockchain/Stacks.toml + env: + - name: STACKS_LOG_PP + value: "1" + - name: BLOCKSTACK_USE_TEST_GENESIS_CHAINSTATE + value: "1" + - name: STACKS_LOG_DEBUG + value: "0" + image: quay.io/hirosystems/stacks-node:devnet-v3 + imagePullPolicy: IfNotPresent + name: stacks-blockchain + ports: + - containerPort: 20444 + name: p2p + protocol: TCP + - containerPort: 20443 + name: rpc + protocol: TCP + volumeMounts: + - mountPath: /src/stacks-blockchain + name: stacks-blockchain + readOnly: true + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + memory: 256Mi + volumes: + - configMap: + name: stacks-blockchain + name: stacks-blockchain \ No newline at end of file diff --git a/templates/stateful-sets/stacks-blockchain-api.template.yaml b/templates/stateful-sets/stacks-blockchain-api.template.yaml new file mode 100644 index 0000000..addd4ee --- /dev/null +++ b/templates/stateful-sets/stacks-blockchain-api.template.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app.kubernetes.io/component: stacks-blockchain-api + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain-api + name: stacks-blockchain-api + namespace: "{namespace}" +spec: + replicas: 1 + serviceName: stacks-blockchain-api + selector: + matchLabels: + app.kubernetes.io/component: stacks-blockchain-api + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain-api + template: + metadata: + labels: + app.kubernetes.io/component: stacks-blockchain-api + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain-api + spec: + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: cloud.google.com/gke-preemptible + operator: DoesNotExist + containers: + - name: stacks-blockchain-api + envFrom: + - configMapRef: + name: stacks-blockchain-api + optional: false + image: hirosystems/stacks-blockchain-api + imagePullPolicy: IfNotPresent + ports: + - containerPort: 3999 + name: api + protocol: TCP + - containerPort: 3700 + name: eventport + protocol: TCP + resources: + requests: + cpu: 250m + memory: 750Mi + limits: + memory: 750Mi + - name: postgres + envFrom: + - configMapRef: + name: stacks-blockchain-api-pg + optional: false + image: postgres:15 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 5432 + name: postgres + protocol: TCP + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: stacks-blockchain-api-pg + subPath: postgres + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + memory: 512Mi + volumeClaimTemplates: + - metadata: + name: stacks-blockchain-api-pg + spec: + accessModes: + - ReadWriteOnce + storageClassName: premium-rwo + resources: + requests: + storage: 1Gi \ No newline at end of file From ec86df2c11bd2beed60434ba262a112834dac07a Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:13:51 -0400 Subject: [PATCH 02/23] add new resource modules --- src/resources/deployment.rs | 17 +++++++++++++++++ src/resources/stateful_set.rs | 15 +++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/resources/deployment.rs create mode 100644 src/resources/stateful_set.rs diff --git a/src/resources/deployment.rs b/src/resources/deployment.rs new file mode 100644 index 0000000..8635cd6 --- /dev/null +++ b/src/resources/deployment.rs @@ -0,0 +1,17 @@ +use std::fmt; +use strum_macros::EnumIter; + +#[derive(EnumIter, Debug)] +pub enum StacksDevnetDeployment { + BitcoindNode, + StacksBlockchain, +} + +impl fmt::Display for StacksDevnetDeployment { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + StacksDevnetDeployment::BitcoindNode => write!(f, "bitcoind-chain-coordinator"), + StacksDevnetDeployment::StacksBlockchain => write!(f, "stacks-blockchain"), + } + } +} diff --git a/src/resources/stateful_set.rs b/src/resources/stateful_set.rs new file mode 100644 index 0000000..c843604 --- /dev/null +++ b/src/resources/stateful_set.rs @@ -0,0 +1,15 @@ +use std::fmt; +use strum_macros::EnumIter; + +#[derive(EnumIter, Debug)] +pub enum StacksDevnetStatefulSet { + StacksBlockchainApi, +} + +impl fmt::Display for StacksDevnetStatefulSet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + StacksDevnetStatefulSet::StacksBlockchainApi => write!(f, "stacks-blockchain-api"), + } + } +} From dea090ea54899bca8a4e950bce73ab7280dbaa73 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:14:30 -0400 Subject: [PATCH 03/23] add new resources to main resource module --- src/resources/mod.rs | 10 ++++++---- src/resources/tests.rs | 15 +++++++++++---- src/template_parser.rs | 20 +++++++++----------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 918143b..15edefa 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -1,18 +1,20 @@ use self::{ - configmap::StacksDevnetConfigmap, pod::StacksDevnetPod, pvc::StacksDevnetPvc, - service::StacksDevnetService, + configmap::StacksDevnetConfigmap, deployment::StacksDevnetDeployment, pod::StacksDevnetPod, + service::StacksDevnetService, stateful_set::StacksDevnetStatefulSet, }; pub mod configmap; +pub mod deployment; pub mod pod; -pub mod pvc; pub mod service; +pub mod stateful_set; pub enum StacksDevnetResource { Configmap(StacksDevnetConfigmap), + Deployment(StacksDevnetDeployment), Pod(StacksDevnetPod), - Pvc(StacksDevnetPvc), Service(StacksDevnetService), + StatefulSet(StacksDevnetStatefulSet), Namespace, } diff --git a/src/resources/tests.rs b/src/resources/tests.rs index c0ff4d0..38a6b7d 100644 --- a/src/resources/tests.rs +++ b/src/resources/tests.rs @@ -1,6 +1,7 @@ use super::{ - pvc::StacksDevnetPvc, + deployment::StacksDevnetDeployment, service::{get_service_from_path_part, get_service_port, get_user_facing_port, ServicePort}, + stateful_set::StacksDevnetStatefulSet, StacksDevnetConfigmap, StacksDevnetPod, StacksDevnetService, }; use test_case::test_case; @@ -24,9 +25,15 @@ fn it_prints_correct_name_for_pod(pod: StacksDevnetPod) -> String { pod.to_string() } -#[test_case(StacksDevnetPvc::StacksBlockchainApiPg => is equal_to "stacks-blockchain-api-pg".to_string(); "for StacksBlockchainApiPg")] -fn it_prints_correct_name_for_pvc(pvc: StacksDevnetPvc) -> String { - pvc.to_string() +#[test_case(StacksDevnetDeployment::BitcoindNode => is equal_to "bitcoind-chain-coordinator".to_string(); "for BitcoindNode")] +#[test_case(StacksDevnetDeployment::StacksBlockchain => is equal_to "stacks-blockchain".to_string(); "for StacksBlockchain")] +fn it_prints_correct_name_for_deployment(deployment: StacksDevnetDeployment) -> String { + deployment.to_string() +} + +#[test_case(StacksDevnetStatefulSet::StacksBlockchainApi => is equal_to "stacks-blockchain-api".to_string(); "for StacksBlockchainApi")] +fn it_prints_correct_name_for_stateful_set(pod: StacksDevnetStatefulSet) -> String { + pod.to_string() } #[test_case(StacksDevnetService::BitcoindNode => is equal_to "bitcoind-chain-coordinator".to_string(); "for BitcoindNode")] diff --git a/src/template_parser.rs b/src/template_parser.rs index 521662f..f912356 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -1,12 +1,12 @@ use crate::resources::{ - configmap::StacksDevnetConfigmap, pod::StacksDevnetPod, pvc::StacksDevnetPvc, - service::StacksDevnetService, StacksDevnetResource, + configmap::StacksDevnetConfigmap, deployment::StacksDevnetDeployment, + service::StacksDevnetService, stateful_set::StacksDevnetStatefulSet, StacksDevnetResource, }; pub fn get_yaml_from_resource(resource: StacksDevnetResource) -> &'static str { match resource { - StacksDevnetResource::Pod(StacksDevnetPod::BitcoindNode) => { - include_str!("../templates/pods/bitcoind-chain-coordinator.template.yaml") + StacksDevnetResource::Deployment(StacksDevnetDeployment::BitcoindNode) => { + include_str!("../templates/deployments/bitcoind-chain-coordinator.template.yaml") } StacksDevnetResource::Service(StacksDevnetService::BitcoindNode) => { include_str!("../templates/services/bitcoind-chain-coordinator.template.yaml") @@ -29,27 +29,25 @@ pub fn get_yaml_from_resource(resource: StacksDevnetResource) -> &'static str { StacksDevnetResource::Configmap(StacksDevnetConfigmap::StacksBlockchainApi) => { include_str!("../templates/configmaps/stacks-blockchain-api.template.yaml") } - StacksDevnetResource::Pod(StacksDevnetPod::StacksBlockchainApi) => { - include_str!("../templates/pods/stacks-blockchain-api.template.yaml") + StacksDevnetResource::StatefulSet(StacksDevnetStatefulSet::StacksBlockchainApi) => { + include_str!("../templates/stateful-sets/stacks-blockchain-api.template.yaml") } StacksDevnetResource::Configmap(StacksDevnetConfigmap::StacksBlockchainApiPg) => { include_str!("../templates/configmaps/stacks-blockchain-api-pg.template.yaml") } - StacksDevnetResource::Pvc(StacksDevnetPvc::StacksBlockchainApiPg) => { - include_str!("../templates/pvcs/stacks-blockchain-api-pg.template.yaml") - } StacksDevnetResource::Service(StacksDevnetService::StacksBlockchainApi) => { include_str!("../templates/services/stacks-blockchain-api.template.yaml") } StacksDevnetResource::Configmap(StacksDevnetConfigmap::StacksBlockchain) => { include_str!("../templates/configmaps/stacks-blockchain.template.yaml") } - StacksDevnetResource::Pod(StacksDevnetPod::StacksBlockchain) => { - include_str!("../templates/pods/stacks-blockchain.template.yaml") + StacksDevnetResource::Deployment(StacksDevnetDeployment::StacksBlockchain) => { + include_str!("../templates/deployments/stacks-blockchain.template.yaml") } StacksDevnetResource::Service(StacksDevnetService::StacksBlockchain) => { include_str!("../templates/services/stacks-blockchain.template.yaml") } StacksDevnetResource::Namespace => include_str!("../templates/namespace.template.yaml"), + StacksDevnetResource::Pod(_) => unreachable!(), } } From 7ca9d3f70c1eb6a14bac1bdc369cd74599cd808f Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:15:12 -0400 Subject: [PATCH 04/23] add new resource creation to main code --- src/config.rs | 2 + src/lib.rs | 321 +++++++++++++++++++++++++++++++++++++------------- src/main.rs | 4 +- src/routes.rs | 3 +- 4 files changed, 246 insertions(+), 84 deletions(-) diff --git a/src/config.rs b/src/config.rs index 465b799..efea780 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,6 +14,7 @@ const CONTRACT_DIR: &str = "/etc/stacks-network/project/contracts"; #[derive(Serialize, Deserialize, Debug)] pub struct ValidatedStacksDevnetConfig { pub namespace: String, + pub user_id: String, pub devnet_config: DevnetConfig, pub accounts: BTreeMap, pub project_manifest_yaml_string: String, @@ -72,6 +73,7 @@ impl StacksDevnetConfig { Ok(ValidatedStacksDevnetConfig { namespace: self.namespace, + user_id: user_id.to_owned(), devnet_config: devnet_config.to_owned(), accounts: self.network_manifest.accounts, project_manifest_yaml_string: project_manifest_yaml_string.to_owned(), diff --git a/src/lib.rs b/src/lib.rs index 35d9791..1c2fcfc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,17 +4,21 @@ use futures::future::try_join4; use hiro_system_kit::{slog, Logger}; use hyper::{body::Bytes, Body, Client as HttpClient, Request, Response, Uri}; use k8s_openapi::{ - api::core::v1::{ConfigMap, Namespace, PersistentVolumeClaim, Pod, Service}, + api::{ + apps::v1::{Deployment, StatefulSet}, + core::v1::{ConfigMap, Namespace, Pod, Service}, + }, NamespaceResourceScope, }; use kube::{ - api::{Api, DeleteParams, PostParams}, + api::{Api, DeleteParams, ListParams, PostParams}, config::KubeConfigOptions, Client, Config, }; use resources::{ - pvc::StacksDevnetPvc, + deployment::StacksDevnetDeployment, service::{get_service_port, ServicePort}, + stateful_set::StacksDevnetStatefulSet, StacksDevnetResource, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; @@ -205,14 +209,14 @@ impl StacksDevnetApiK8sManager { }); }; - self.deploy_bitcoin_node_pod(&config).await?; + self.deploy_bitcoin_node(&config).await?; sleep(Duration::from_secs(5)); - self.deploy_stacks_node_pod(&config).await?; + self.deploy_stacks_blockchain(&config).await?; if !config.disable_stacks_api { - self.deploy_stacks_api_pod(&namespace).await?; + self.deploy_stacks_blockchain_api(&config).await?; } Ok(()) } @@ -221,9 +225,26 @@ impl StacksDevnetApiK8sManager { match self.check_any_devnet_assets_exist(&namespace).await? { true => { let mut errors = vec![]; - let pods: Vec = StacksDevnetPod::iter().map(|p| p.to_string()).collect(); - for pod in pods { - if let Err(e) = self.delete_resource::(namespace, &pod).await { + let deployments: Vec = StacksDevnetDeployment::iter() + .map(|p| p.to_string()) + .collect(); + for deployment in deployments { + if let Err(e) = self + .delete_resource::(namespace, &deployment) + .await + { + errors.push(e); + } + } + + let stateful_sets: Vec = StacksDevnetStatefulSet::iter() + .map(|p| p.to_string()) + .collect(); + for stateful_set in stateful_sets { + if let Err(e) = self + .delete_resource::(namespace, &stateful_set) + .await + { errors.push(e); } } @@ -248,15 +269,6 @@ impl StacksDevnetApiK8sManager { } } - let pvcs: Vec = StacksDevnetPvc::iter().map(|s| s.to_string()).collect(); - for pvc in pvcs { - if let Err(e) = self - .delete_resource::(namespace, &pvc) - .await - { - errors.push(e); - } - } if errors.is_empty() { Ok(()) } else if errors.len() == 1 { @@ -341,36 +353,36 @@ impl StacksDevnetApiK8sManager { &namespace ) }); - for pod in StacksDevnetPod::iter() { + for deployment in StacksDevnetDeployment::iter() { if self - .check_resource_exists::(namespace, &pod.to_string()) + .check_resource_exists::(namespace, &deployment.to_string()) .await? { return Ok(true); } } - for configmap in StacksDevnetConfigmap::iter() { + for stateful_set in StacksDevnetStatefulSet::iter() { if self - .check_resource_exists::(namespace, &configmap.to_string()) + .check_resource_exists::(namespace, &stateful_set.to_string()) .await? { return Ok(true); } } - for service in StacksDevnetService::iter() { + for configmap in StacksDevnetConfigmap::iter() { if self - .check_resource_exists::(namespace, &service.to_string()) + .check_resource_exists::(namespace, &configmap.to_string()) .await? { return Ok(true); } } - for pvc in StacksDevnetPvc::iter() { + for service in StacksDevnetService::iter() { if self - .check_resource_exists::(namespace, &pvc.to_string()) + .check_resource_exists::(namespace, &service.to_string()) .await? { return Ok(true); @@ -391,36 +403,36 @@ impl StacksDevnetApiK8sManager { &namespace ) }); - for pod in StacksDevnetPod::iter() { + for deployment in StacksDevnetDeployment::iter() { if !self - .check_resource_exists::(namespace, &pod.to_string()) + .check_resource_exists::(namespace, &deployment.to_string()) .await? { return Ok(false); } } - for configmap in StacksDevnetConfigmap::iter() { + for stateful_set in StacksDevnetStatefulSet::iter() { if !self - .check_resource_exists::(namespace, &configmap.to_string()) + .check_resource_exists::(namespace, &stateful_set.to_string()) .await? { return Ok(false); } } - for service in StacksDevnetService::iter() { + for configmap in StacksDevnetConfigmap::iter() { if !self - .check_resource_exists::(namespace, &service.to_string()) + .check_resource_exists::(namespace, &configmap.to_string()) .await? { return Ok(false); } } - for pvc in StacksDevnetPvc::iter() { + for service in StacksDevnetService::iter() { if !self - .check_resource_exists::(namespace, &pvc.to_string()) + .check_resource_exists::(namespace, &service.to_string()) .await? { return Ok(false); @@ -433,6 +445,7 @@ impl StacksDevnetApiK8sManager { async fn get_pod_status_info( &self, namespace: &str, + user_id: &str, pod: StacksDevnetPod, ) -> Result { let context = format!("NAMESPACE: {}, POD: {}", namespace, pod); @@ -441,24 +454,33 @@ impl StacksDevnetApiK8sManager { slog::info!(logger, "getting pod status {}", context) }); let pod_api: Api = Api::namespaced(self.client.to_owned(), &namespace); - let pod_name = pod.to_string(); - match pod_api.get_status(&pod_name).await { - Ok(pod_with_status) => match pod_with_status.status { - Some(status) => { - self.ctx.try_log(|logger: &hiro_system_kit::Logger| { - slog::info!(logger, "successfully retrieved pod status {}", context) - }); - let start_time = match status.start_time { - Some(st) => Some(st.0.to_string()), - None => None, - }; - Ok(PodStatusResponse { - status: status.phase, - start_time, - }) + let pod_label_selector = format!("app.kubernetes.io/component={}", pod); + let user_label_selector = format!("app.kubernetes.io/instance={}", user_id); + let label_selector = format!("{pod_label_selector},{user_label_selector}"); + let lp = ListParams::default() + .match_any() + .labels(&label_selector) + .limit(1); + match pod_api.list(&lp).await { + Ok(pods) => { + let pod_with_status = &pods.items[0]; + match &pod_with_status.status { + Some(status) => { + self.ctx.try_log(|logger: &hiro_system_kit::Logger| { + slog::info!(logger, "successfully retrieved pod status {}", context) + }); + let start_time = match &status.start_time { + Some(st) => Some(st.0.to_string()), + None => None, + }; + Ok(PodStatusResponse { + status: status.phase.to_owned(), + start_time, + }) + } + None => Ok(PodStatusResponse::default()), } - None => Ok(PodStatusResponse::default()), - }, + } Err(e) => { let (msg, code) = match e { kube::Error::Api(api_error) => (api_error.message, api_error.code), @@ -554,6 +576,7 @@ impl StacksDevnetApiK8sManager { pub async fn get_devnet_info( &self, namespace: &str, + user_id: &str, ) -> Result { let context = format!("NAMESPACE: {}", namespace); @@ -587,9 +610,17 @@ impl StacksDevnetApiK8sManager { }, chain_info, ) = try_join4( - self.get_pod_status_info(&namespace, StacksDevnetPod::BitcoindNode), - self.get_pod_status_info(&namespace, StacksDevnetPod::StacksBlockchain), - self.get_pod_status_info(&namespace, StacksDevnetPod::StacksBlockchainApi), + self.get_pod_status_info(&namespace, user_id, StacksDevnetPod::BitcoindNode), + self.get_pod_status_info( + &namespace, + user_id, + StacksDevnetPod::StacksBlockchain, + ), + self.get_pod_status_info( + &namespace, + user_id, + StacksDevnetPod::StacksBlockchainApi, + ), self.get_stacks_v2_info(&namespace), ) .await?; @@ -772,21 +803,140 @@ impl StacksDevnetApiK8sManager { } } - async fn deploy_pod(&self, pod: StacksDevnetPod, namespace: &str) -> Result<(), DevNetError> { - let mut pod: Pod = self.get_resource_from_file(StacksDevnetResource::Pod(pod))?; + async fn deploy_deployment( + &self, + deployment: StacksDevnetDeployment, + namespace: &str, + user_id: &str, + ) -> Result<(), DevNetError> { + let mut deployment: Deployment = + self.get_resource_from_file(StacksDevnetResource::Deployment(deployment))?; + + let key = "app.kubernetes.io/instance".to_string(); + let user_id = user_id.to_owned(); + + if let Some(mut labels) = deployment.clone().metadata.labels { + if let Some(label) = labels.get_mut(&key) { + *label = user_id.clone(); + } else { + labels.insert(key.clone(), user_id.clone()); + } + deployment.metadata.labels = Some(labels); + } + + if let Some(mut spec) = deployment.clone().spec { + if let Some(mut match_labels) = spec.selector.match_labels { + if let Some(match_label) = match_labels.get_mut(&key) { + *match_label = user_id.clone(); + } else { + match_labels.insert(key.clone(), user_id.clone()); + } + spec.selector.match_labels = Some(match_labels); + } - pod.metadata.namespace = Some(namespace.to_owned()); - self.deploy_resource(namespace, pod, "pod").await + if let Some(mut metadata) = spec.template.metadata { + if let Some(mut labels) = metadata.labels { + if let Some(label) = labels.get_mut(&key) { + *label = user_id.clone(); + } else { + labels.insert(key.clone(), user_id.clone()); + } + metadata.labels = Some(labels); + } + spec.template.metadata = Some(metadata); + } + + deployment.spec = Some(spec); + } + + deployment.metadata.namespace = Some(namespace.to_owned()); + self.deploy_resource(namespace, deployment, "deployment") + .await + } + + async fn deploy_stateful_set( + &self, + stateful_set: StacksDevnetStatefulSet, + namespace: &str, + user_id: &str, + ) -> Result<(), DevNetError> { + let mut stateful_set: StatefulSet = + self.get_resource_from_file(StacksDevnetResource::StatefulSet(stateful_set))?; + let key = "app.kubernetes.io/instance".to_string(); + let user_id = user_id.to_owned(); + + if let Some(mut labels) = stateful_set.clone().metadata.labels { + if let Some(label) = labels.get_mut(&key) { + *label = user_id.clone(); + } else { + labels.insert(key.clone(), user_id.clone()); + } + stateful_set.metadata.labels = Some(labels); + } + + if let Some(mut spec) = stateful_set.clone().spec { + if let Some(mut match_labels) = spec.selector.match_labels { + if let Some(match_label) = match_labels.get_mut(&key) { + *match_label = user_id.clone(); + } else { + match_labels.insert(key.clone(), user_id.clone()); + } + spec.selector.match_labels = Some(match_labels); + } + + if let Some(mut metadata) = spec.template.metadata { + if let Some(mut labels) = metadata.labels { + if let Some(label) = labels.get_mut(&key) { + *label = user_id.clone(); + } else { + labels.insert(key.clone(), user_id.clone()); + } + metadata.labels = Some(labels); + } + spec.template.metadata = Some(metadata); + } + + stateful_set.spec = Some(spec); + } + + stateful_set.metadata.namespace = Some(namespace.to_owned()); + self.deploy_resource(namespace, stateful_set, "stateful_set") + .await } async fn deploy_service( &self, service: StacksDevnetService, namespace: &str, + user_id: &str, ) -> Result<(), DevNetError> { let mut service: Service = self.get_resource_from_file(StacksDevnetResource::Service(service))?; + let key = "app.kubernetes.io/instance".to_string(); + let user_id = user_id.to_owned(); + + if let Some(mut labels) = service.clone().metadata.labels { + if let Some(label) = labels.get_mut(&key) { + *label = user_id.clone(); + } else { + labels.insert(key.clone(), user_id.clone()); + } + service.metadata.labels = Some(labels); + } + + if let Some(mut spec) = service.clone().spec { + if let Some(mut selector_map) = spec.selector { + if let Some(selector_entry) = selector_map.get_mut(&key) { + *selector_entry = user_id.clone(); + } else { + selector_map.insert(key.clone(), user_id.clone()); + } + spec.selector = Some(selector_map); + } + + service.spec = Some(spec); + } service.metadata.namespace = Some(namespace.to_owned()); self.deploy_resource(namespace, service, "service").await } @@ -813,20 +963,12 @@ impl StacksDevnetApiK8sManager { .await } - async fn deploy_pvc(&self, pvc: StacksDevnetPvc, namespace: &str) -> Result<(), DevNetError> { - let mut pvc: PersistentVolumeClaim = - self.get_resource_from_file(StacksDevnetResource::Pvc(pvc))?; - - pvc.metadata.namespace = Some(namespace.to_owned()); - - self.deploy_resource(namespace, pvc, "pvc").await - } - - async fn deploy_bitcoin_node_pod( + async fn deploy_bitcoin_node( &self, config: &ValidatedStacksDevnetConfig, ) -> Result<(), DevNetError> { let namespace = &config.namespace; + let user_id = &config.user_id; let devnet_config = &config.devnet_config; let bitcoin_rpc_port = @@ -909,20 +1051,21 @@ impl StacksDevnetApiK8sManager { ) .await?; - self.deploy_pod(StacksDevnetPod::BitcoindNode, &namespace) + self.deploy_deployment(StacksDevnetDeployment::BitcoindNode, &namespace, &user_id) .await?; - self.deploy_service(StacksDevnetService::BitcoindNode, namespace) + self.deploy_service(StacksDevnetService::BitcoindNode, namespace, &user_id) .await?; Ok(()) } - async fn deploy_stacks_node_pod( + async fn deploy_stacks_blockchain( &self, config: &ValidatedStacksDevnetConfig, ) -> Result<(), DevNetError> { let namespace = &config.namespace; + let user_id = &config.user_id; let devnet_config = &config.devnet_config; let chain_coordinator_ingestion_port = @@ -1086,16 +1229,25 @@ impl StacksDevnetApiK8sManager { ) .await?; - self.deploy_pod(StacksDevnetPod::StacksBlockchain, &namespace) - .await?; + self.deploy_deployment( + StacksDevnetDeployment::StacksBlockchain, + &namespace, + &user_id, + ) + .await?; - self.deploy_service(StacksDevnetService::StacksBlockchain, namespace) + self.deploy_service(StacksDevnetService::StacksBlockchain, namespace, &user_id) .await?; Ok(()) } - async fn deploy_stacks_api_pod(&self, namespace: &str) -> Result<(), DevNetError> { + async fn deploy_stacks_blockchain_api( + &self, + config: &ValidatedStacksDevnetConfig, + ) -> Result<(), DevNetError> { + let namespace = &config.namespace; + let user_id = &config.user_id; // configmap env vars for pg conatainer let stacks_api_pg_env = Vec::from([ ("POSTGRES_PASSWORD".into(), "postgres".into()), @@ -1144,14 +1296,19 @@ impl StacksDevnetApiK8sManager { ) .await?; - self.deploy_pvc(StacksDevnetPvc::StacksBlockchainApiPg, &namespace) - .await?; - - self.deploy_pod(StacksDevnetPod::StacksBlockchainApi, &namespace) - .await?; + self.deploy_stateful_set( + StacksDevnetStatefulSet::StacksBlockchainApi, + &namespace, + user_id, + ) + .await?; - self.deploy_service(StacksDevnetService::StacksBlockchainApi, &namespace) - .await?; + self.deploy_service( + StacksDevnetService::StacksBlockchainApi, + &namespace, + &user_id, + ) + .await?; Ok(()) } diff --git a/src/main.rs b/src/main.rs index 5974cc1..7df0e9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -149,7 +149,9 @@ async fn handle_request( if path_parts.subroute.is_none() { return match method { &Method::DELETE => handle_delete_devnet(k8s_manager, &network, responder).await, - &Method::GET => handle_get_devnet(k8s_manager, &network, responder, ctx).await, + &Method::GET => { + handle_get_devnet(k8s_manager, &network, &user_id, responder, ctx).await + } &Method::HEAD => handle_check_devnet(k8s_manager, &network, responder).await, _ => responder .err_method_not_allowed("can only GET/DELETE/HEAD at provided route".into()), diff --git a/src/routes.rs b/src/routes.rs index 1d807cf..f2eba06 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -77,10 +77,11 @@ pub async fn handle_delete_devnet( pub async fn handle_get_devnet( k8s_manager: StacksDevnetApiK8sManager, network: &str, + user_id: &str, responder: Responder, ctx: Context, ) -> Result, Infallible> { - match k8s_manager.get_devnet_info(&network).await { + match k8s_manager.get_devnet_info(&network, user_id).await { Ok(devnet_info) => match serde_json::to_vec(&devnet_info) { Ok(body) => responder.ok_with_json(Body::from(body)), Err(e) => { From c87c320b410e6dfbc2843f8134576dcf36ac875d Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:15:29 -0400 Subject: [PATCH 05/23] update service selectors --- .../services/bitcoind-chain-coordinator.template.yaml | 10 +++++++++- templates/services/stacks-blockchain-api.template.yaml | 10 +++++++++- templates/services/stacks-blockchain.template.yaml | 10 +++++++++- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/templates/services/bitcoind-chain-coordinator.template.yaml b/templates/services/bitcoind-chain-coordinator.template.yaml index 9c782e0..c8ce732 100644 --- a/templates/services/bitcoind-chain-coordinator.template.yaml +++ b/templates/services/bitcoind-chain-coordinator.template.yaml @@ -1,6 +1,11 @@ apiVersion: v1 kind: Service metadata: + labels: + app.kubernetes.io/component: bitcoind-chain-coordinator + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: bitcoind-chain-coordinator name: bitcoind-chain-coordinator namespace: "{namespace}" spec: @@ -22,4 +27,7 @@ spec: protocol: TCP targetPort: 20446 selector: - name: bitcoind-chain-coordinator + app.kubernetes.io/component: bitcoind-chain-coordinator + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: bitcoind-chain-coordinator diff --git a/templates/services/stacks-blockchain-api.template.yaml b/templates/services/stacks-blockchain-api.template.yaml index ea5a95b..580844b 100644 --- a/templates/services/stacks-blockchain-api.template.yaml +++ b/templates/services/stacks-blockchain-api.template.yaml @@ -1,6 +1,11 @@ apiVersion: v1 kind: Service metadata: + labels: + app.kubernetes.io/component: stacks-blockchain-api + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain-api name: stacks-blockchain-api namespace: "{namespace}" spec: @@ -18,4 +23,7 @@ spec: protocol: TCP targetPort: 3700 selector: - name: stacks-blockchain-api + app.kubernetes.io/component: stacks-blockchain-api + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain-api diff --git a/templates/services/stacks-blockchain.template.yaml b/templates/services/stacks-blockchain.template.yaml index 0daa77e..632aad3 100644 --- a/templates/services/stacks-blockchain.template.yaml +++ b/templates/services/stacks-blockchain.template.yaml @@ -1,6 +1,11 @@ apiVersion: v1 kind: Service metadata: + labels: + app.kubernetes.io/component: stacks-blockchain + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain name: stacks-blockchain namespace: "{namespace}" spec: @@ -12,4 +17,7 @@ spec: port: 20443 protocol: TCP selector: - name: stacks-blockchain + app.kubernetes.io/component: stacks-blockchain + app.kubernetes.io/instance: "{user_id}" + app.kubernetes.io/managed-by: stacks-devnet-api + app.kubernetes.io/name: stacks-blockchain From f6b834d2e3aa3fdb621057bae3ab0eeadc2818a4 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:15:42 -0400 Subject: [PATCH 06/23] remove pod/pvc templates --- .../bitcoind-chain-coordinator.template.yaml | 76 ------------------- .../pods/stacks-blockchain-api.template.yaml | 42 ---------- .../pods/stacks-blockchain.template.yaml | 38 ---------- .../stacks-blockchain-api-pg.template.yaml | 15 ---- 4 files changed, 171 deletions(-) delete mode 100644 templates/pods/bitcoind-chain-coordinator.template.yaml delete mode 100644 templates/pods/stacks-blockchain-api.template.yaml delete mode 100644 templates/pods/stacks-blockchain.template.yaml delete mode 100644 templates/pvcs/stacks-blockchain-api-pg.template.yaml diff --git a/templates/pods/bitcoind-chain-coordinator.template.yaml b/templates/pods/bitcoind-chain-coordinator.template.yaml deleted file mode 100644 index 4db1864..0000000 --- a/templates/pods/bitcoind-chain-coordinator.template.yaml +++ /dev/null @@ -1,76 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - labels: - name: bitcoind-chain-coordinator - name: bitcoind-chain-coordinator - namespace: "{namespace}" -spec: - containers: - - command: - - /usr/local/bin/bitcoind - - -conf=/etc/bitcoin/bitcoin.conf - - -nodebuglogfile - - -pid=/run/bitcoind.pid - image: quay.io/hirosystems/bitcoind:devnet-v3 - imagePullPolicy: IfNotPresent - name: bitcoind - ports: - - containerPort: 18444 - name: p2p - protocol: TCP - - containerPort: 18443 - name: rpc - protocol: TCP - volumeMounts: - - mountPath: /etc/bitcoin - name: bitcoind - readOnly: true - - command: - - ./stacks-network - - --namespace=$(NAMESPACE) - - --manifest-path=/etc/stacks-network/project/Clarinet.toml - - --network-manifest-path=/etc/stacks-network/project/settings/Devnet.toml - - --deployment-plan-path=/etc/stacks-network/project/deployments/default.devnet-plan.yaml - - --project-root-path=/etc/stacks-network/project/ - env: - - name: NAMESPACE - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.namespace - image: hirosystems/stacks-network-orchestrator:rpc-error - imagePullPolicy: Always - name: chain-coordinator - ports: - - containerPort: 20445 - name: coordinator-in - protocol: TCP - - containerPort: 20446 - name: coordinator-con - protocol: TCP - volumeMounts: - - mountPath: /etc/stacks-network/project - name: project-manifest - - mountPath: /etc/stacks-network/project/settings - name: devnet - - mountPath: /etc/stacks-network/project/deployments - name: deployment-plan - - mountPath: /etc/stacks-network/project/contracts - name: project-dir - volumes: - - configMap: - name: bitcoind - name: bitcoind - - configMap: - name: project-manifest - name: project-manifest - - configMap: - name: devnet - name: devnet - - configMap: - name: deployment-plan - name: deployment-plan - - configMap: - name: project-dir - name: project-dir diff --git a/templates/pods/stacks-blockchain-api.template.yaml b/templates/pods/stacks-blockchain-api.template.yaml deleted file mode 100644 index 94f58de..0000000 --- a/templates/pods/stacks-blockchain-api.template.yaml +++ /dev/null @@ -1,42 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - labels: - name: stacks-blockchain-api - name: stacks-blockchain-api - namespace: "{namespace}" -spec: - containers: - - name: stacks-blockchain-api - envFrom: - - configMapRef: - name: stacks-blockchain-api - optional: false - image: hirosystems/stacks-blockchain-api - imagePullPolicy: IfNotPresent - ports: - - containerPort: 3999 - name: api - protocol: TCP - - containerPort: 3700 - name: eventport - protocol: TCP - - name: postgres - envFrom: - - configMapRef: - name: stacks-blockchain-api-pg - optional: false - image: postgres:14 - imagePullPolicy: IfNotPresent - ports: - - containerPort: 5432 - name: postgres - protocol: TCP - volumeMounts: - - mountPath: /var/lib/postgresql/data - name: stacks-blockchain-api-pg - subPath: postgres - volumes: - - name: stacks-blockchain-api-pg - persistentVolumeClaim: - claimName: stacks-blockchain-api-pg diff --git a/templates/pods/stacks-blockchain.template.yaml b/templates/pods/stacks-blockchain.template.yaml deleted file mode 100644 index 421c4a2..0000000 --- a/templates/pods/stacks-blockchain.template.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - labels: - name: stacks-blockchain - name: stacks-blockchain - namespace: "{namespace}" -spec: - containers: - - command: - - stacks-node - - start - - --config=/src/stacks-blockchain/Stacks.toml - env: - - name: STACKS_LOG_PP - value: "1" - - name: BLOCKSTACK_USE_TEST_GENESIS_CHAINSTATE - value: "1" - - name: STACKS_LOG_DEBUG - value: "0" - image: quay.io/hirosystems/stacks-node:devnet-v3 - imagePullPolicy: IfNotPresent - name: stacks-blockchain - ports: - - containerPort: 20444 - name: p2p - protocol: TCP - - containerPort: 20443 - name: rpc - protocol: TCP - volumeMounts: - - mountPath: /src/stacks-blockchain - name: stacks-blockchain - readOnly: true - volumes: - - configMap: - name: stacks-blockchain - name: stacks-blockchain \ No newline at end of file diff --git a/templates/pvcs/stacks-blockchain-api-pg.template.yaml b/templates/pvcs/stacks-blockchain-api-pg.template.yaml deleted file mode 100644 index 97df3f3..0000000 --- a/templates/pvcs/stacks-blockchain-api-pg.template.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: stacks-blockchain-api-pg - namespace: "{namespace}" -spec: - accessModes: - - ReadWriteOnce - resources: - limits: - storage: 750Mi - requests: - storage: 500Mi - storageClassName: premium-rwo - volumeMode: Filesystem From 7c4ff2e47dcfd8ef717549af637c8fe4d47ec3a3 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 20:16:19 -0400 Subject: [PATCH 07/23] update clusterrole permissions for new assets --- templates/stacks-devnet-api.template.yaml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/templates/stacks-devnet-api.template.yaml b/templates/stacks-devnet-api.template.yaml index cf2e91f..bdf07c3 100644 --- a/templates/stacks-devnet-api.template.yaml +++ b/templates/stacks-devnet-api.template.yaml @@ -11,7 +11,10 @@ metadata: name: stacks-devnet-api rules: - apiGroups: [""] - resources: ["pods", "pods/status", "services", "configmaps", "persistentvolumeclaims"] + resources: ["pods", "pods/status", "services", "configmaps"] + verbs: ["get", "delete", "create"] + - apiGroups: ["apps"] + resources: ["deployments", "statefulsets"] verbs: ["get", "delete", "create"] - apiGroups: [""] resources: ["namespaces"] @@ -46,10 +49,10 @@ spec: containers: - command: ["stacks-devnet-api"] name: stacks-devnet-api - image: hirosystems/stacks-devnet-api:latest + image: stacks-devnet-api imagePullPolicy: IfNotPresent ports: - - containerPort: 8477 + - containerPort: 8478 name: api protocol: TCP volumeMounts: @@ -71,7 +74,7 @@ spec: - name: api port: 8477 protocol: TCP - targetPort: 8477 + targetPort: 8478 nodePort: 30000 selector: name: stacks-devnet-api From ed745bded92950247e577a61a0f8eaf0d570fa3b Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 21:05:26 -0400 Subject: [PATCH 08/23] increase resource allocation --- .../deployments/bitcoind-chain-coordinator.template.yaml | 4 ++-- templates/deployments/stacks-blockchain.template.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/deployments/bitcoind-chain-coordinator.template.yaml b/templates/deployments/bitcoind-chain-coordinator.template.yaml index a49d7e4..e77b2ee 100644 --- a/templates/deployments/bitcoind-chain-coordinator.template.yaml +++ b/templates/deployments/bitcoind-chain-coordinator.template.yaml @@ -54,9 +54,9 @@ spec: resources: requests: cpu: 250m - memory: 256Mi + memory: 750Mi limits: - memory: 256Mi + memory: 750Mi - command: - ./stacks-network - --namespace=$(NAMESPACE) diff --git a/templates/deployments/stacks-blockchain.template.yaml b/templates/deployments/stacks-blockchain.template.yaml index 813fc94..578ae93 100644 --- a/templates/deployments/stacks-blockchain.template.yaml +++ b/templates/deployments/stacks-blockchain.template.yaml @@ -60,9 +60,9 @@ spec: resources: requests: cpu: 250m - memory: 256Mi + memory: 750Mi limits: - memory: 256Mi + memory: 750Mi volumes: - configMap: name: stacks-blockchain From 6561533f155fbfadfa2f99adf110df3dd0acd496 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Thu, 28 Sep 2023 21:05:40 -0400 Subject: [PATCH 09/23] update permissions --- templates/stacks-devnet-api.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/stacks-devnet-api.template.yaml b/templates/stacks-devnet-api.template.yaml index bdf07c3..a2343da 100644 --- a/templates/stacks-devnet-api.template.yaml +++ b/templates/stacks-devnet-api.template.yaml @@ -12,10 +12,10 @@ metadata: rules: - apiGroups: [""] resources: ["pods", "pods/status", "services", "configmaps"] - verbs: ["get", "delete", "create"] + verbs: ["get", "delete", "create", "list"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] - verbs: ["get", "delete", "create"] + verbs: ["get", "delete", "create", "list"] - apiGroups: [""] resources: ["namespaces"] verbs: ["get"] From 18100fb2fe4d9c426525663092e47fe7dd7d2399 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 29 Sep 2023 12:00:17 -0400 Subject: [PATCH 10/23] add todo's for resource allocation --- .../deployments/bitcoind-chain-coordinator.template.yaml | 4 ++-- templates/deployments/stacks-blockchain.template.yaml | 4 ++-- templates/stateful-sets/stacks-blockchain-api.template.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/deployments/bitcoind-chain-coordinator.template.yaml b/templates/deployments/bitcoind-chain-coordinator.template.yaml index e77b2ee..c68f2cc 100644 --- a/templates/deployments/bitcoind-chain-coordinator.template.yaml +++ b/templates/deployments/bitcoind-chain-coordinator.template.yaml @@ -54,9 +54,9 @@ spec: resources: requests: cpu: 250m - memory: 750Mi + memory: 750Mi # todo: revisit allocation limits: - memory: 750Mi + memory: 750Mi # todo: revisit allocation - command: - ./stacks-network - --namespace=$(NAMESPACE) diff --git a/templates/deployments/stacks-blockchain.template.yaml b/templates/deployments/stacks-blockchain.template.yaml index 578ae93..6b7f003 100644 --- a/templates/deployments/stacks-blockchain.template.yaml +++ b/templates/deployments/stacks-blockchain.template.yaml @@ -60,9 +60,9 @@ spec: resources: requests: cpu: 250m - memory: 750Mi + memory: 750Mi # todo: revisit allocation limits: - memory: 750Mi + memory: 750Mi # todo: revisit allocation volumes: - configMap: name: stacks-blockchain diff --git a/templates/stateful-sets/stacks-blockchain-api.template.yaml b/templates/stateful-sets/stacks-blockchain-api.template.yaml index addd4ee..4c7c7ee 100644 --- a/templates/stateful-sets/stacks-blockchain-api.template.yaml +++ b/templates/stateful-sets/stacks-blockchain-api.template.yaml @@ -50,9 +50,9 @@ spec: resources: requests: cpu: 250m - memory: 750Mi + memory: 750Mi # todo: revisit allocation limits: - memory: 750Mi + memory: 750Mi # todo: revisit allocation - name: postgres envFrom: - configMapRef: From c0f17df331dcf2c3be896faf11281c1c5cc97bcd Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 29 Sep 2023 12:08:34 -0400 Subject: [PATCH 11/23] specify connection types for service ports --- .../services/bitcoind-chain-coordinator.template.yaml | 8 ++++---- templates/services/stacks-blockchain-api.template.yaml | 6 +++--- templates/services/stacks-blockchain.template.yaml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/services/bitcoind-chain-coordinator.template.yaml b/templates/services/bitcoind-chain-coordinator.template.yaml index c8ce732..ddcaac7 100644 --- a/templates/services/bitcoind-chain-coordinator.template.yaml +++ b/templates/services/bitcoind-chain-coordinator.template.yaml @@ -10,19 +10,19 @@ metadata: namespace: "{namespace}" spec: ports: - - name: p2p + - name: tcp-p2p port: 18444 protocol: TCP targetPort: 18444 - - name: rpc + - name: tcp-rpc port: 18443 protocol: TCP targetPort: 18443 - - name: coordinator-in + - name: http-coordinator-in port: 20445 protocol: TCP targetPort: 20445 - - name: coordinator-con + - name: http-coordinator-con port: 20446 protocol: TCP targetPort: 20446 diff --git a/templates/services/stacks-blockchain-api.template.yaml b/templates/services/stacks-blockchain-api.template.yaml index 580844b..02f9456 100644 --- a/templates/services/stacks-blockchain-api.template.yaml +++ b/templates/services/stacks-blockchain-api.template.yaml @@ -10,15 +10,15 @@ metadata: namespace: "{namespace}" spec: ports: - - name: api + - name: http-api port: 3999 protocol: TCP targetPort: 3999 - - name: postgres + - name: tcp-postgres port: 5432 protocol: TCP targetPort: 5432 - - name: eventport + - name: tcp-eventport port: 3700 protocol: TCP targetPort: 3700 diff --git a/templates/services/stacks-blockchain.template.yaml b/templates/services/stacks-blockchain.template.yaml index 632aad3..da0c733 100644 --- a/templates/services/stacks-blockchain.template.yaml +++ b/templates/services/stacks-blockchain.template.yaml @@ -10,10 +10,10 @@ metadata: namespace: "{namespace}" spec: ports: - - name: p2p + - name: tcp-p2p port: 20444 protocol: TCP - - name: rpc + - name: http-rpc port: 20443 protocol: TCP selector: From 047d792b211672d1cdf0ba7fd9396fd383ffcf55 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 29 Sep 2023 13:04:17 -0400 Subject: [PATCH 12/23] disable broken test --- src/tests/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/mod.rs b/src/tests/mod.rs index e4f8b3f..99bbf5f 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -113,7 +113,7 @@ enum TestBody { } #[test_case("/api/v1/network/{namespace}", Method::DELETE, None, false => is equal_to (StatusCode::OK, "Ok".to_string()); "200 for network DELETE request")] -#[test_case("/api/v1/network/{namespace}", Method::DELETE, None, true => using assert_cannot_delete_devnet_multiple_errs; "500 for network DELETE request with multiple errors")] +// #[test_case("/api/v1/network/{namespace}", Method::DELETE, None, true => using assert_cannot_delete_devnet_multiple_errs; "500 for network DELETE request with multiple errors")] #[test_case("/api/v1/networks", Method::POST, Some(TestBody::CreateNetwork), true => using assert_cannot_create_devnet_err; "409 for create network POST request if devnet exists")] #[test_case("/api/v1/network/{namespace}", Method::GET, None, true => using assert_get_network; "200 for network GET request to existing network")] #[test_case("/api/v1/network/{namespace}", Method::HEAD, None, true => is equal_to (StatusCode::OK, "Ok".to_string()); "200 for network HEAD request to existing network")] From 941fcba0d88a787e1faeb87ca103047286d4e2a2 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Fri, 29 Sep 2023 13:05:08 -0400 Subject: [PATCH 13/23] update ci clusterrole permissions --- templates/ci/stacks-devnet-api.template.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/templates/ci/stacks-devnet-api.template.yaml b/templates/ci/stacks-devnet-api.template.yaml index 3948dda..e570393 100644 --- a/templates/ci/stacks-devnet-api.template.yaml +++ b/templates/ci/stacks-devnet-api.template.yaml @@ -11,8 +11,11 @@ metadata: name: stacks-devnet-api rules: - apiGroups: [""] - resources: ["pods", "pods/status", "services", "configmaps", "persistentvolumeclaims"] - verbs: ["get", "delete", "create"] + resources: ["pods", "pods/status", "services", "configmaps"] + verbs: ["get", "delete", "create", "list"] + - apiGroups: ["apps"] + resources: ["deployments", "statefulsets"] + verbs: ["get", "delete", "create", "list"] - apiGroups: [""] resources: ["namespaces"] verbs: ["get"] From c9c59f545cd8de0f744da5c5e0f5af0e93e90073 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Tue, 3 Oct 2023 15:11:17 -0400 Subject: [PATCH 14/23] check for pods by label when checking for any assets --- src/lib.rs | 120 ++++++++++++++++++++++++++++++++++++++++++++--- src/main.rs | 8 +++- src/routes.rs | 9 +++- src/tests/mod.rs | 5 +- 4 files changed, 130 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1c2fcfc..9ff180a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,6 +41,10 @@ use crate::resources::configmap::StacksDevnetConfigmap; use crate::resources::pod::StacksDevnetPod; use crate::resources::service::{get_service_url, StacksDevnetService}; +const COMPONENT_SELECTOR: &str = "app.kubernetes.io/component"; +const USER_SELECTOR: &str = "app.kubernetes.io/instance"; +const NAME_SELECTOR: &str = "app.kubernetes.io/name"; + #[derive(Clone, Debug)] pub struct DevNetError { pub message: String, @@ -177,6 +181,7 @@ impl StacksDevnetApiK8sManager { config: ValidatedStacksDevnetConfig, ) -> Result<(), DevNetError> { let namespace = &config.namespace; + let user_id = &config.user_id; let context = format!("NAMESPACE: {}", &namespace); let namespace_exists = self.check_namespace_exists(&namespace).await?; @@ -196,7 +201,9 @@ impl StacksDevnetApiK8sManager { } } - let any_assets_exist = self.check_any_devnet_assets_exist(&namespace).await?; + let any_assets_exist = self + .check_any_devnet_assets_exist(&namespace, &user_id) + .await?; if any_assets_exist { let msg = format!( "cannot create devnet because assets already exist {}", @@ -221,8 +228,11 @@ impl StacksDevnetApiK8sManager { Ok(()) } - pub async fn delete_devnet(&self, namespace: &str) -> Result<(), DevNetError> { - match self.check_any_devnet_assets_exist(&namespace).await? { + pub async fn delete_devnet(&self, namespace: &str, user_id: &str) -> Result<(), DevNetError> { + match self + .check_any_devnet_assets_exist(namespace, user_id) + .await? + { true => { let mut errors = vec![]; let deployments: Vec = StacksDevnetDeployment::iter() @@ -345,6 +355,7 @@ impl StacksDevnetApiK8sManager { pub async fn check_any_devnet_assets_exist( &self, namespace: &str, + user_id: &str, ) -> Result { self.ctx.try_log(|logger| { slog::info!( @@ -371,6 +382,15 @@ impl StacksDevnetApiK8sManager { } } + for pod in StacksDevnetPod::iter() { + if self + .check_resource_exists_by_label::(namespace, &pod.to_string(), user_id) + .await? + { + return Ok(true); + } + } + for configmap in StacksDevnetConfigmap::iter() { if self .check_resource_exists::(namespace, &configmap.to_string()) @@ -454,13 +474,18 @@ impl StacksDevnetApiK8sManager { slog::info!(logger, "getting pod status {}", context) }); let pod_api: Api = Api::namespaced(self.client.to_owned(), &namespace); - let pod_label_selector = format!("app.kubernetes.io/component={}", pod); - let user_label_selector = format!("app.kubernetes.io/instance={}", user_id); - let label_selector = format!("{pod_label_selector},{user_label_selector}"); + + let pod_label_selector = format!("{COMPONENT_SELECTOR}={pod}"); + let user_label_selector = format!("{USER_SELECTOR}={user_id}"); + let name_label_selector = format!("{NAME_SELECTOR}={pod}"); + let label_selector = + format!("{pod_label_selector},{user_label_selector},{name_label_selector}"); + let lp = ListParams::default() .match_any() .labels(&label_selector) .limit(1); + match pod_api.list(&lp).await { Ok(pods) => { let pod_with_status = &pods.items[0]; @@ -675,6 +700,67 @@ impl StacksDevnetApiK8sManager { } } + async fn get_resource_by_label>( + &self, + namespace: &str, + name: &str, + user_id: &str, + ) -> Result, DevNetError> + where + ::DynamicType: Default, + K: Clone, + K: DeserializeOwned, + K: std::fmt::Debug, + K: Serialize, + { + let resource_api: Api = Api::namespaced(self.client.to_owned(), &namespace); + + let pod_label_selector = format!("{COMPONENT_SELECTOR}={name}"); + let user_label_selector = format!("{USER_SELECTOR}={user_id}"); + let label_selector = format!("{pod_label_selector},{user_label_selector}"); + let lp = ListParams::default() + .match_any() + .labels(&label_selector) + .limit(1); + + let resource_details = format!( + "RESOURCE: {}, NAME: {}, NAMESPACE: {}", + std::any::type_name::(), + name, + namespace + ); + self.ctx + .try_log(|logger| slog::info!(logger, "fetching {}", resource_details)); + + match resource_api.list(&lp).await { + Ok(pods) => { + if pods.items.len() > 0 { + let pod = &pods.items[0]; + Ok(Some(pod.clone())) + } else { + Ok(None) + } + } + Err(e) => { + let (msg, code) = match e { + kube::Error::Api(api_error) => { + if api_error.code == 404 { + return Ok(None); + } + (api_error.message, api_error.code) + } + e => (e.to_string(), 500), + }; + let msg = format!("failed to fetch {}, ERROR: {}", resource_details, msg); + self.ctx.try_log(|logger| slog::error!(logger, "{}", msg)); + Err(DevNetError { + message: msg, + code: code, + }) + } + } + } + async fn get_resource>( &self, namespace: &str, @@ -728,6 +814,28 @@ impl StacksDevnetApiK8sManager { } } + async fn check_resource_exists_by_label>( + &self, + namespace: &str, + name: &str, + user_id: &str, + ) -> Result + where + ::DynamicType: Default, + K: Clone, + K: DeserializeOwned, + K: std::fmt::Debug, + K: Serialize, + { + match self + .get_resource_by_label::(namespace, name, user_id) + .await? + { + Some(_) => Ok(true), + None => Ok(false), + } + } + async fn check_resource_exists>( &self, namespace: &str, diff --git a/src/main.rs b/src/main.rs index 7df0e9b..491eebb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,11 +148,15 @@ async fn handle_request( // so it must be a request to DELETE a network or GET network info if path_parts.subroute.is_none() { return match method { - &Method::DELETE => handle_delete_devnet(k8s_manager, &network, responder).await, + &Method::DELETE => { + handle_delete_devnet(k8s_manager, &network, &user_id, responder).await + } &Method::GET => { handle_get_devnet(k8s_manager, &network, &user_id, responder, ctx).await } - &Method::HEAD => handle_check_devnet(k8s_manager, &network, responder).await, + &Method::HEAD => { + handle_check_devnet(k8s_manager, &network, &user_id, responder).await + } _ => responder .err_method_not_allowed("can only GET/DELETE/HEAD at provided route".into()), }; diff --git a/src/routes.rs b/src/routes.rs index f2eba06..a940e8a 100644 --- a/src/routes.rs +++ b/src/routes.rs @@ -63,9 +63,10 @@ pub async fn handle_new_devnet( pub async fn handle_delete_devnet( k8s_manager: StacksDevnetApiK8sManager, network: &str, + user_id: &str, responder: Responder, ) -> Result, Infallible> { - match k8s_manager.delete_devnet(network).await { + match k8s_manager.delete_devnet(network, user_id).await { Ok(_) => responder.ok(), Err(e) => { let msg = format!("error deleting network {}: {}", &network, e.message); @@ -101,9 +102,13 @@ pub async fn handle_get_devnet( pub async fn handle_check_devnet( k8s_manager: StacksDevnetApiK8sManager, network: &str, + user_id: &str, responder: Responder, ) -> Result, Infallible> { - match k8s_manager.check_any_devnet_assets_exist(&network).await { + match k8s_manager + .check_any_devnet_assets_exist(network, user_id) + .await + { Ok(assets_exist) => match assets_exist { true => responder.ok(), false => responder.err_not_found("not found".to_string()), diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 99bbf5f..86f3763 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -113,7 +113,7 @@ enum TestBody { } #[test_case("/api/v1/network/{namespace}", Method::DELETE, None, false => is equal_to (StatusCode::OK, "Ok".to_string()); "200 for network DELETE request")] -// #[test_case("/api/v1/network/{namespace}", Method::DELETE, None, true => using assert_cannot_delete_devnet_multiple_errs; "500 for network DELETE request with multiple errors")] +#[test_case("/api/v1/network/{namespace}", Method::DELETE, None, true => using assert_cannot_delete_devnet_multiple_errs; "500 for network DELETE request with multiple errors")] #[test_case("/api/v1/networks", Method::POST, Some(TestBody::CreateNetwork), true => using assert_cannot_create_devnet_err; "409 for create network POST request if devnet exists")] #[test_case("/api/v1/network/{namespace}", Method::GET, None, true => using assert_get_network; "200 for network GET request to existing network")] #[test_case("/api/v1/network/{namespace}", Method::HEAD, None, true => is equal_to (StatusCode::OK, "Ok".to_string()); "200 for network HEAD request to existing network")] @@ -144,6 +144,7 @@ async fn it_responds_to_valid_requests_with_deploy( let mut config = get_template_config(); config.namespace = namespace.to_owned(); let validated_config = config.to_validated_config(&namespace, ctx.clone()).unwrap(); + let user_id = &namespace; let _ = k8s_manager.deploy_devnet(validated_config).await.unwrap(); // short delay to allow assets to start sleep(Duration::new(5, 0)); @@ -168,7 +169,7 @@ async fn it_responds_to_valid_requests_with_deploy( let mut status = response.status(); if tear_down { - match k8s_manager.delete_devnet(namespace).await { + match k8s_manager.delete_devnet(namespace, user_id).await { Ok(_) => {} Err(e) => { body_str = e.message; From c104451fa0a4b17b5cda52aab7537054e222121a Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Tue, 3 Oct 2023 15:17:34 -0400 Subject: [PATCH 15/23] fix container port --- templates/stacks-devnet-api.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/stacks-devnet-api.template.yaml b/templates/stacks-devnet-api.template.yaml index a2343da..d8fe3b0 100644 --- a/templates/stacks-devnet-api.template.yaml +++ b/templates/stacks-devnet-api.template.yaml @@ -52,7 +52,7 @@ spec: image: stacks-devnet-api imagePullPolicy: IfNotPresent ports: - - containerPort: 8478 + - containerPort: 8477 name: api protocol: TCP volumeMounts: @@ -74,7 +74,7 @@ spec: - name: api port: 8477 protocol: TCP - targetPort: 8478 + targetPort: 8477 nodePort: 30000 selector: name: stacks-devnet-api From a1a2acde541921765521acfc7e27f98b8234ea91 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 10:21:19 -0400 Subject: [PATCH 16/23] add back pvc to resources --- src/resources/mod.rs | 4 +++- src/template_parser.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/resources/mod.rs b/src/resources/mod.rs index 15edefa..ff8041d 100644 --- a/src/resources/mod.rs +++ b/src/resources/mod.rs @@ -1,11 +1,12 @@ use self::{ configmap::StacksDevnetConfigmap, deployment::StacksDevnetDeployment, pod::StacksDevnetPod, - service::StacksDevnetService, stateful_set::StacksDevnetStatefulSet, + pvc::StacksDevnetPvc, service::StacksDevnetService, stateful_set::StacksDevnetStatefulSet, }; pub mod configmap; pub mod deployment; pub mod pod; +pub mod pvc; pub mod service; pub mod stateful_set; @@ -13,6 +14,7 @@ pub enum StacksDevnetResource { Configmap(StacksDevnetConfigmap), Deployment(StacksDevnetDeployment), Pod(StacksDevnetPod), + Pvc(StacksDevnetPvc), Service(StacksDevnetService), StatefulSet(StacksDevnetStatefulSet), Namespace, diff --git a/src/template_parser.rs b/src/template_parser.rs index f912356..afa97d0 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -48,6 +48,6 @@ pub fn get_yaml_from_resource(resource: StacksDevnetResource) -> &'static str { include_str!("../templates/services/stacks-blockchain.template.yaml") } StacksDevnetResource::Namespace => include_str!("../templates/namespace.template.yaml"), - StacksDevnetResource::Pod(_) => unreachable!(), + StacksDevnetResource::Pod(_) | StacksDevnetResource::Pvc(_) => unreachable!(), } } From 1645a1b758cef16f4f079550793aaba1f4f5182c Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 10:21:27 -0400 Subject: [PATCH 17/23] delete pvc --- src/lib.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9ff180a..400de22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,7 +6,7 @@ use hyper::{body::Bytes, Body, Client as HttpClient, Request, Response, Uri}; use k8s_openapi::{ api::{ apps::v1::{Deployment, StatefulSet}, - core::v1::{ConfigMap, Namespace, Pod, Service}, + core::v1::{ConfigMap, Namespace, PersistentVolumeClaim, Pod, Service}, }, NamespaceResourceScope, }; @@ -17,6 +17,7 @@ use kube::{ }; use resources::{ deployment::StacksDevnetDeployment, + pvc::StacksDevnetPvc, service::{get_service_port, ServicePort}, stateful_set::StacksDevnetStatefulSet, StacksDevnetResource, @@ -279,6 +280,17 @@ impl StacksDevnetApiK8sManager { } } + let pvcs: Vec = + StacksDevnetPvc::iter().map(|pvc| pvc.to_string()).collect(); + for pvc in pvcs { + if let Err(e) = self + .delete_resource_by_label::(namespace, &pvc, user_id) + .await + { + errors.push(e); + } + } + if errors.is_empty() { Ok(()) } else if errors.len() == 1 { @@ -409,6 +421,18 @@ impl StacksDevnetApiK8sManager { } } + for pvc in StacksDevnetPvc::iter() { + if self + .check_resource_exists_by_label::( + namespace, + &pvc.to_string(), + user_id, + ) + .await? + { + return Ok(true); + } + } Ok(false) } @@ -717,7 +741,9 @@ impl StacksDevnetApiK8sManager { let pod_label_selector = format!("{COMPONENT_SELECTOR}={name}"); let user_label_selector = format!("{USER_SELECTOR}={user_id}"); - let label_selector = format!("{pod_label_selector},{user_label_selector}"); + let name_label_selector = format!("{NAME_SELECTOR}={name}"); + let label_selector = + format!("{pod_label_selector},{user_label_selector},{name_label_selector}"); let lp = ListParams::default() .match_any() .labels(&label_selector) @@ -1464,6 +1490,63 @@ impl StacksDevnetApiK8sManager { } } } + + async fn delete_resource_by_label>( + &self, + namespace: &str, + resource_name: &str, + user_id: &str, + ) -> Result<(), DevNetError> + where + ::DynamicType: Default, + K: Clone, + K: DeserializeOwned, + K: std::fmt::Debug, + { + let api: Api = Api::namespaced(self.client.to_owned(), &namespace); + let dp = DeleteParams::default(); + + let pod_label_selector = format!("{COMPONENT_SELECTOR}={resource_name}"); + let user_label_selector = format!("{USER_SELECTOR}={user_id}"); + let name_label_selector = format!("{NAME_SELECTOR}={resource_name}"); + let label_selector = + format!("{pod_label_selector},{user_label_selector},{name_label_selector}"); + + let lp = ListParams::default() + .match_any() + .labels(&label_selector) + .limit(1); + + let resource_details = format!( + "RESOURCE: {}, NAME: {}, NAMESPACE: {}", + std::any::type_name::(), + resource_name, + namespace + ); + self.ctx + .try_log(|logger| slog::info!(logger, "deleting {}", resource_details)); + match api.delete_collection(&dp, &lp).await { + Ok(_) => { + self.ctx.try_log(|logger| { + slog::info!(logger, "successfully deleted {}", resource_details) + }); + Ok(()) + } + Err(e) => { + let e = match e { + kube::Error::Api(api_error) => (api_error.message, api_error.code), + e => (e.to_string(), 500), + }; + let msg = format!("failed to delete {}, ERROR: {}", resource_details, e.0); + self.ctx.try_log(|logger| slog::error!(logger, "{}", msg)); + Err(DevNetError { + message: msg, + code: e.1, + }) + } + } + } + pub async fn delete_namespace(&self, namespace_str: &str) -> Result<(), DevNetError> { if cfg!(debug_assertions) { use kube::ResourceExt; From d50e4e455538427bba899c5ecabe3d408e9cdf7a Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 12:56:47 -0400 Subject: [PATCH 18/23] fix image version --- .../deployments/bitcoind-chain-coordinator.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/deployments/bitcoind-chain-coordinator.template.yaml b/templates/deployments/bitcoind-chain-coordinator.template.yaml index c68f2cc..5e747f9 100644 --- a/templates/deployments/bitcoind-chain-coordinator.template.yaml +++ b/templates/deployments/bitcoind-chain-coordinator.template.yaml @@ -70,8 +70,8 @@ spec: fieldRef: apiVersion: v1 fieldPath: metadata.namespace - image: stacks-network-orchestrator - imagePullPolicy: Never + image: hirosystems/stacks-network-orchestrator@sha256:e9c88e46adb10deba74e29883533de747a2200665f919d1708a5ea0f2638d32a + imagePullPolicy: IfNotPresent name: chain-coordinator ports: - containerPort: 20445 From 0924df240f52786a1d9383a3d818e2ade4b77171 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 13:32:51 -0400 Subject: [PATCH 19/23] fix permissions --- templates/stacks-devnet-api.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/stacks-devnet-api.template.yaml b/templates/stacks-devnet-api.template.yaml index d8fe3b0..694b8f9 100644 --- a/templates/stacks-devnet-api.template.yaml +++ b/templates/stacks-devnet-api.template.yaml @@ -11,8 +11,8 @@ metadata: name: stacks-devnet-api rules: - apiGroups: [""] - resources: ["pods", "pods/status", "services", "configmaps"] - verbs: ["get", "delete", "create", "list"] + resources: ["pods", "pods/status", "services", "configmaps", "persistentvolumeclaims"] + verbs: ["get", "delete", "create", "list", "deletecollection"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["get", "delete", "create", "list"] From 9a3bb21d25cd66e45c197c1b7b738d66b863b5fc Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 13:59:01 -0400 Subject: [PATCH 20/23] fix resource name for pvc --- src/resources/pvc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/pvc.rs b/src/resources/pvc.rs index 81605e8..58404b4 100644 --- a/src/resources/pvc.rs +++ b/src/resources/pvc.rs @@ -9,7 +9,7 @@ pub enum StacksDevnetPvc { impl fmt::Display for StacksDevnetPvc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - StacksDevnetPvc::StacksBlockchainApiPg => write!(f, "stacks-blockchain-api-pg"), + StacksDevnetPvc::StacksBlockchainApiPg => write!(f, "stacks-blockchain-api"), } } } From 5b798adf8a4d99ed43dca5ccfb6f6c8a514afdc4 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 16:14:43 -0400 Subject: [PATCH 21/23] update ci yaml --- templates/ci/stacks-devnet-api.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/ci/stacks-devnet-api.template.yaml b/templates/ci/stacks-devnet-api.template.yaml index e570393..1c1b679 100644 --- a/templates/ci/stacks-devnet-api.template.yaml +++ b/templates/ci/stacks-devnet-api.template.yaml @@ -11,8 +11,8 @@ metadata: name: stacks-devnet-api rules: - apiGroups: [""] - resources: ["pods", "pods/status", "services", "configmaps"] - verbs: ["get", "delete", "create", "list"] + resources: ["pods", "pods/status", "services", "configmaps", "persistentvolumeclaims"] + verbs: ["get", "delete", "create", "list", "deletecollection"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets"] verbs: ["get", "delete", "create", "list"] From 30ad1eee0f2bc16930159d133a0ed66ff237663f Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Wed, 4 Oct 2023 16:19:25 -0400 Subject: [PATCH 22/23] fix devnet image --- templates/stacks-devnet-api.template.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/stacks-devnet-api.template.yaml b/templates/stacks-devnet-api.template.yaml index 694b8f9..2f2727d 100644 --- a/templates/stacks-devnet-api.template.yaml +++ b/templates/stacks-devnet-api.template.yaml @@ -49,7 +49,7 @@ spec: containers: - command: ["stacks-devnet-api"] name: stacks-devnet-api - image: stacks-devnet-api + image: hirosystems/stacks-devnet-api:latest imagePullPolicy: IfNotPresent ports: - containerPort: 8477 From 9190724590d61346b739aeb352eb052cb1d38950 Mon Sep 17 00:00:00 2001 From: MicaiahReid Date: Mon, 9 Oct 2023 00:09:09 -0400 Subject: [PATCH 23/23] simplify pvc name --- templates/stateful-sets/stacks-blockchain-api.template.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/stateful-sets/stacks-blockchain-api.template.yaml b/templates/stateful-sets/stacks-blockchain-api.template.yaml index 4c7c7ee..81e8101 100644 --- a/templates/stateful-sets/stacks-blockchain-api.template.yaml +++ b/templates/stateful-sets/stacks-blockchain-api.template.yaml @@ -66,7 +66,7 @@ spec: protocol: TCP volumeMounts: - mountPath: /var/lib/postgresql/data - name: stacks-blockchain-api-pg + name: pg subPath: postgres resources: requests: @@ -76,7 +76,7 @@ spec: memory: 512Mi volumeClaimTemplates: - metadata: - name: stacks-blockchain-api-pg + name: pg spec: accessModes: - ReadWriteOnce