Add 'update' command as well
This commit is contained in:
parent
86c962e0cf
commit
1ded4cec81
@ -40,6 +40,12 @@ class DockerDeployer(Deployer):
|
|||||||
except DockerException as e:
|
except DockerException as e:
|
||||||
raise DeployerException(e)
|
raise DeployerException(e)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
try:
|
||||||
|
return self.docker.compose.restart()
|
||||||
|
except DockerException as e:
|
||||||
|
raise DeployerException(e)
|
||||||
|
|
||||||
def ps(self):
|
def ps(self):
|
||||||
try:
|
try:
|
||||||
return self.docker.compose.ps()
|
return self.docker.compose.ps()
|
||||||
|
@ -107,6 +107,14 @@ def down_operation(ctx, delete_volumes, extra_args_list):
|
|||||||
ctx.obj.deployer.down(timeout=timeout_arg, volumes=delete_volumes)
|
ctx.obj.deployer.down(timeout=timeout_arg, volumes=delete_volumes)
|
||||||
|
|
||||||
|
|
||||||
|
def update_operation(ctx):
|
||||||
|
global_context = ctx.parent.parent.obj
|
||||||
|
if not global_context.dry_run:
|
||||||
|
if global_context.verbose:
|
||||||
|
print("Running compose update")
|
||||||
|
ctx.obj.deployer.update()
|
||||||
|
|
||||||
|
|
||||||
def ps_operation(ctx):
|
def ps_operation(ctx):
|
||||||
global_context = ctx.parent.parent.obj
|
global_context = ctx.parent.parent.obj
|
||||||
if not global_context.dry_run:
|
if not global_context.dry_run:
|
||||||
|
@ -27,6 +27,10 @@ class Deployer(ABC):
|
|||||||
def down(self, timeout, volumes):
|
def down(self, timeout, volumes):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def update(self):
|
||||||
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def ps(self):
|
def ps(self):
|
||||||
pass
|
pass
|
||||||
|
@ -19,7 +19,7 @@ import sys
|
|||||||
from stack_orchestrator import constants
|
from stack_orchestrator import constants
|
||||||
from stack_orchestrator.deploy.images import push_images_operation
|
from stack_orchestrator.deploy.images import push_images_operation
|
||||||
from stack_orchestrator.deploy.deploy import up_operation, down_operation, ps_operation, port_operation
|
from stack_orchestrator.deploy.deploy import up_operation, down_operation, ps_operation, port_operation
|
||||||
from stack_orchestrator.deploy.deploy import exec_operation, logs_operation, create_deploy_context
|
from stack_orchestrator.deploy.deploy import exec_operation, logs_operation, create_deploy_context, update_operation
|
||||||
from stack_orchestrator.deploy.deploy_types import DeployCommandContext
|
from stack_orchestrator.deploy.deploy_types import DeployCommandContext
|
||||||
from stack_orchestrator.deploy.deployment_context import DeploymentContext
|
from stack_orchestrator.deploy.deployment_context import DeploymentContext
|
||||||
from stack_orchestrator.deploy.webapp import update_from_registry as webapp_update
|
from stack_orchestrator.deploy.webapp import update_from_registry as webapp_update
|
||||||
@ -161,3 +161,10 @@ def status(ctx):
|
|||||||
def update_from_registry(ctx, laconic_config, app_crn, deployment_crn, force):
|
def update_from_registry(ctx, laconic_config, app_crn, deployment_crn, force):
|
||||||
ctx.obj = make_deploy_context(ctx)
|
ctx.obj = make_deploy_context(ctx)
|
||||||
webapp_update.update(ctx, str(ctx.obj.stack.parent), laconic_config, app_crn, deployment_crn, force)
|
webapp_update.update(ctx, str(ctx.obj.stack.parent), laconic_config, app_crn, deployment_crn, force)
|
||||||
|
|
||||||
|
|
||||||
|
@command.command()
|
||||||
|
@click.pass_context
|
||||||
|
def update(ctx):
|
||||||
|
ctx.obj = make_deploy_context(ctx)
|
||||||
|
update_operation(ctx)
|
||||||
|
@ -189,6 +189,7 @@ class ClusterInfo:
|
|||||||
container = client.V1Container(
|
container = client.V1Container(
|
||||||
name=container_name,
|
name=container_name,
|
||||||
image=image_to_use,
|
image=image_to_use,
|
||||||
|
image_pull_policy="Always",
|
||||||
env=envs_from_environment_variables_map(self.environment_variables.map),
|
env=envs_from_environment_variables_map(self.environment_variables.map),
|
||||||
ports=[client.V1ContainerPort(container_port=port)],
|
ports=[client.V1ContainerPort(container_port=port)],
|
||||||
volume_mounts=volume_mounts,
|
volume_mounts=volume_mounts,
|
||||||
|
@ -13,6 +13,8 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
# along with this program. If not, see <http:#www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from kubernetes import client, config
|
from kubernetes import client, config
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ class K8sDeployer(Deployer):
|
|||||||
networking_api: client.NetworkingV1Api
|
networking_api: client.NetworkingV1Api
|
||||||
k8s_namespace: str = "default"
|
k8s_namespace: str = "default"
|
||||||
kind_cluster_name: str
|
kind_cluster_name: str
|
||||||
cluster_info : ClusterInfo
|
cluster_info: ClusterInfo
|
||||||
deployment_dir: Path
|
deployment_dir: Path
|
||||||
deployment_context: DeploymentContext
|
deployment_context: DeploymentContext
|
||||||
|
|
||||||
@ -230,6 +232,33 @@ class K8sDeployer(Deployer):
|
|||||||
log_data = self.core_api.read_namespaced_pod_log(k8s_pod_name, namespace="default", container="test")
|
log_data = self.core_api.read_namespaced_pod_log(k8s_pod_name, namespace="default", container="test")
|
||||||
return log_stream_from_string(log_data)
|
return log_stream_from_string(log_data)
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.connect_api()
|
||||||
|
ref_deployment = self.cluster_info.get_deployment()
|
||||||
|
|
||||||
|
deployment = self.apps_api.read_namespaced_deployment(
|
||||||
|
name=ref_deployment.metadata.name,
|
||||||
|
namespace=self.k8s_namespace
|
||||||
|
)
|
||||||
|
|
||||||
|
new_env = ref_deployment.spec.template.spec.containers[0].env
|
||||||
|
for container in deployment.spec.template.spec.containers:
|
||||||
|
old_env = container.env
|
||||||
|
if old_env != new_env:
|
||||||
|
container.env = new_env
|
||||||
|
|
||||||
|
deployment.spec.template.metadata.annotations = {
|
||||||
|
"kubectl.kubernetes.io/restartedAt": datetime.utcnow()
|
||||||
|
.replace(tzinfo=timezone.utc)
|
||||||
|
.isoformat()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.apps_api.patch_namespaced_deployment(
|
||||||
|
name=ref_deployment.metadata.name,
|
||||||
|
namespace=self.k8s_namespace,
|
||||||
|
body=deployment
|
||||||
|
)
|
||||||
|
|
||||||
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
|
def run(self, image: str, command=None, user=None, volumes=None, entrypoint=None, env={}, ports=[], detach=False):
|
||||||
# We need to figure out how to do this -- check why we're being called first
|
# We need to figure out how to do this -- check why we're being called first
|
||||||
pass
|
pass
|
||||||
|
@ -74,12 +74,8 @@ def config_changed(deploy_record, deployment_dir):
|
|||||||
|
|
||||||
|
|
||||||
def redeploy(laconic_config, app_record, deploy_record, deploy_crn, deployment_dir):
|
def redeploy(laconic_config, app_record, deploy_record, deploy_crn, deployment_dir):
|
||||||
print("Stopping deployment ...")
|
print("Updating deployment ...")
|
||||||
result = subprocess.run(["laconic-so", "deployment", "--dir", deployment_dir, "stop"])
|
result = subprocess.run(["laconic-so", "deployment", "--dir", deployment_dir, "update"])
|
||||||
result.check_returncode()
|
|
||||||
|
|
||||||
print("Starting deployment ...")
|
|
||||||
result = subprocess.run(["laconic-so", "deployment", "--dir", deployment_dir, "start"])
|
|
||||||
result.check_returncode()
|
result.check_returncode()
|
||||||
|
|
||||||
spec = yaml.full_load(open(os.path.join(deployment_dir, "spec.yml")))
|
spec = yaml.full_load(open(os.path.join(deployment_dir, "spec.yml")))
|
||||||
@ -143,19 +139,20 @@ def update(ctx, deployment_dir, laconic_config, app_crn, deploy_crn, force=False
|
|||||||
if app_record["id"] == deploy_record.get("attributes", {}).get("application"):
|
if app_record["id"] == deploy_record.get("attributes", {}).get("application"):
|
||||||
print("Deployment %s has latest application: %s" % (deploy_crn, app_record["id"]))
|
print("Deployment %s has latest application: %s" % (deploy_crn, app_record["id"]))
|
||||||
else:
|
else:
|
||||||
|
needs_update = True
|
||||||
print("Found updated application record eligible for deployment %s (old: %s, new: %s)" % (
|
print("Found updated application record eligible for deployment %s (old: %s, new: %s)" % (
|
||||||
deploy_crn, deploy_record.get("id"), app_record["id"]))
|
deploy_crn, deploy_record.get("id"), app_record["id"]))
|
||||||
build_image(app_record, deployment_dir)
|
build_image(app_record, deployment_dir)
|
||||||
needs_update = True
|
|
||||||
|
|
||||||
# check config
|
# check config
|
||||||
if config_changed(deploy_record, deployment_dir):
|
if config_changed(deploy_record, deployment_dir):
|
||||||
|
needs_update = True
|
||||||
old = None
|
old = None
|
||||||
if deploy_record:
|
if deploy_record:
|
||||||
old = json.loads(deploy_record["attributes"]["meta"]["config"])
|
print(deploy_record)
|
||||||
|
old = json.loads(deploy_record["attributes"]["meta"])["config"]
|
||||||
print("Deployment %s has changed config: (old: %s, new: %s)" % (
|
print("Deployment %s has changed config: (old: %s, new: %s)" % (
|
||||||
deploy_crn, old, config_hash(deployment_dir)))
|
deploy_crn, old, config_hash(deployment_dir)))
|
||||||
needs_update = True
|
|
||||||
else:
|
else:
|
||||||
print("Deployment %s has latest config: %s" % (
|
print("Deployment %s has latest config: %s" % (
|
||||||
deploy_crn, json.loads(deploy_record["attributes"]["meta"])["config"]))
|
deploy_crn, json.loads(deploy_record["attributes"]["meta"])["config"]))
|
||||||
|
Loading…
Reference in New Issue
Block a user