summaryrefslogtreecommitdiffstats
path: root/src/job/runnable.rs
blob: 971cb304c71b2af18892beb0c8c2cb5884528bcd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use getset::Getters;
use uuid::Uuid;
use anyhow::anyhow;
use anyhow::Context;
use anyhow::Error;
use anyhow::Result;
use resiter::Map;

use crate::job::Job;
use crate::job::JobResource;
use crate::package::Package;
use crate::package::Script;
use crate::package::ScriptBuilder;
use crate::phase::PhaseName;
use crate::util::docker::ImageName;
use crate::filestore::MergedStores;
use crate::package::ParseDependency;

/// A job configuration that can be run. All inputs are clear here.
#[derive(Debug, Getters)]
pub struct RunnableJob {
    #[getset(get = "pub")]
    uuid: Uuid,

    #[getset(get = "pub")]
    package:  Package,

    #[getset(get = "pub")]
    image:    ImageName,

    #[getset(get = "pub")]
    script:   Script,

    #[getset(get = "pub")]
    resources: Vec<JobResource>,
}

impl RunnableJob {
    pub fn build_from_job(job: Job, merged_stores: &MergedStores) -> Result<Self> {
        let script = ScriptBuilder::new(&job.script_shebang)
            .build(&job.package, &job.script_phases)?;

        let resources = job.package()
            .dependencies()
            .build()
            .into_iter()
            .map(|runtime_dep| {
                let (name, version) = runtime_dep.parse_as_name_and_version()?;
                let mut a = merged_stores.get_artifact_by_name_and_version(&name, &version)?;

                if a.is_empty() {
                    Err(anyhow!("Cannot find dependency: {:?} {:?}", name, version))
                        .context("Building a runnable job")
                        .map_err(Error::from)
                } else {
                    a.sort();
                    let a_len = a.len();
                    let found_dependency = a.into_iter().next().unwrap(); // save by above check
                    if a_len > 1 {
                        warn!("Found more than one dependency for {:?} {:?}", name, version);
                        warn!("Using: {:?}", found_dependency);
                        warn!("Please investigate, this might be a BUG");
                    }

                    Ok(JobResource::Artifact(found_dependency.clone()))
                }
            })
            .collect::<Result<Vec<JobResource>>>()?;

        Ok(RunnableJob {
            uuid: job.uuid,
            package: job.package,
            image: job.image,
            resources: job.resources.into_iter().chain(resources.into_iter()).collect(),

            script,
        })

    }
}