Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add registry type and url to worker payload for ECR dispatching #3967

Merged
merged 1 commit into from Nov 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -7,12 +7,10 @@ <h3>
<input name="name" #name="ngModel" [(ngModel)]="model.name" placeholder="Integration name" [class.invalid]="name.invalid && name.dirty"
required>
</div>
<!-- TED TODO: Add this for the disabled services when we're ready
<div class="form-input-full-width">
<div class="form-input-full-width" *ngIf="data.type !== 'docker'">
<label>Registry Url</label>
<input name="url" #url="ngModel" [(ngModel)]="model.url" placeholder="Registry URL (Optional)" pattern="https?://.+" [class.invalid]="url.invalid && url.dirty">
<input name="registry_url" #registry_url="ngModel" [(ngModel)]="model.registry_url" placeholder="Registry URL" [class.invalid]="registry_url.invalid && registry_url.dirty">
</div>
-->
<div class="form-input-full-width">
<label>Docker Hub Username</label>
<input name="username" #username="ngModel" [(ngModel)]="model.username" placeholder="username" [class.invalid]="username.invalid && username.dirty"
Expand Down
Expand Up @@ -86,20 +86,25 @@ export class IntegrationCredentialsFormDialog implements OnDestroy {
}

onSubmit() {
this.store.dispatch(validateIntegrationCredentials(this.model.username, this.model.password, this.token, this.data.type));
let unsubscribe;
if (this.data.type === 'docker') {
this.store.dispatch(validateIntegrationCredentials(this.model.username, this.model.password, this.token, this.data.type));
let unsubscribe;

unsubscribe = this.store.subscribe(state => {
const creds = state.origins.currentIntegrations.ui.creds;
unsubscribe = this.store.subscribe(state => {
const creds = state.origins.currentIntegrations.ui.creds;

if (!creds.validating && creds.validated) {
unsubscribe();
if (!creds.validating && creds.validated) {
unsubscribe();

if (creds.valid) {
setTimeout(() => this.dialogRef.close(this.model), 750);
if (creds.valid) {
setTimeout(() => this.dialogRef.close(this.model), 750);
}
}
}
});
});
} else {
// We can currently only validate DockerHub creds (╯︵╰,)
this.dialogRef.close(this.model);
}
}

close() {
Expand Down
Expand Up @@ -37,8 +37,9 @@ <h3>
</span>
</button>
</mat-grid-tile>
-->
<mat-grid-tile>
<button id="amazon" mat-raised-button disabled (click)="addIntegration('amazon')" class="mat-elevation-z">
<button id="amazon" mat-raised-button (click)="addIntegration('amazon')" class="mat-elevation-z">
<span class="icon logo amazon">
<hab-icon symbol="amazon"></hab-icon>
</span>
Expand All @@ -50,6 +51,7 @@ <h3>
</span>
</button>
</mat-grid-tile>
<!--
<mat-grid-tile>
<button id="azure" mat-raised-button disabled (click)="addIntegration('azure')">
<span class="icon logo azure">
Expand Down
9 changes: 9 additions & 0 deletions components/builder-worker/src/runner/docker.rs
Expand Up @@ -45,6 +45,8 @@ const DOCKER_HOST_ENVVAR: &'static str = "DOCKER_HOST";
pub struct DockerExporterSpec {
pub username: String,
pub password: String,
pub registry_type: String,
pub registry_url: Option<String>,
pub docker_hub_repo_name: String,
pub latest_tag: bool,
pub version_tag: bool,
Expand Down Expand Up @@ -115,6 +117,13 @@ impl<'a> DockerExporter<'a> {
cmd.arg("--password");
cmd.arg(&self.spec.password);
cmd.arg("--rm-image");
if let Some(ref registry_url) = self.spec.registry_url {
cmd.arg("--registry-url");
cmd.arg(registry_url);
}
cmd.arg("--registry-type");
cmd.arg(&self.spec.registry_type);

cmd.arg(self.workspace.last_built()?.path); // Locally built artifact
debug!(
"building docker export command, cmd={}",
Expand Down
1 change: 0 additions & 1 deletion components/builder-worker/src/runner/mod.rs
Expand Up @@ -385,7 +385,6 @@ impl Runner {
self.workspace.job.set_package_ident(op_ident);
return Err(Error::BuildFailure(status.code().unwrap_or(-1)));
}

if self.has_docker_integration() {
// TODO fn: This check should be updated in PackageArchive is check for run hooks.
if self.workspace.last_built()?.is_a_service() {
Expand Down
4 changes: 2 additions & 2 deletions components/builder-worker/src/runner/studio.rs
Expand Up @@ -13,7 +13,6 @@
// limitations under the License.

use std::net::IpAddr;
use std::os::unix::io::FromRawFd;
use std::os::unix::process::CommandExt;
use std::path::PathBuf;
use std::process::{Command, ExitStatus, Stdio};
Expand Down Expand Up @@ -114,7 +113,7 @@ impl<'a> Studio<'a> {
// TED TODO: This will not work on windows. A more robust threading solution will be required for log_pipe
// to support consuming stderr and stdout.
// This manifests when a child starts (studio) and has an error (often unseen) then suddenly stops all execution.
cmd.stderr(unsafe { Stdio::from_raw_fd(1) }); // Log stderr to stdout
cmd.stderr(Stdio::null()); // Log stderr to stdout
cmd.arg("-k"); // Origin key
cmd.arg(self.workspace.job.origin());
cmd.arg("build");
Expand Down Expand Up @@ -177,6 +176,7 @@ impl<'a> Studio<'a> {
} else {
let mut cmd = Command::new(&*STUDIO_PROGRAM);
cmd.env_clear();
debug!("HAB_CACHE_KEY_PATH: {:?}", key_path());
cmd.env("NO_ARTIFACT_PATH", "true"); // Disables artifact cache mounting
cmd.env("HAB_CACHE_KEY_PATH", key_path()); // Sets key cache to build user's home

Expand Down
67 changes: 30 additions & 37 deletions components/builder-worker/src/runner/util.rs
Expand Up @@ -56,12 +56,7 @@ pub fn validate_integrations(workspace: &Workspace) -> Result<()> {
}

let prj_integration = prj_integrations.first().unwrap();
if prj_integration.get_integration() != "docker" {
return Err(Error::InvalidIntegrations(format!(
"integration '{}' not supported",
prj_integration.get_integration()
)));
}

if prj_integration.get_integration_name() != "default" {
return Err(Error::InvalidIntegrations(format!(
"integration name '{}' not supported",
Expand Down Expand Up @@ -139,18 +134,7 @@ pub fn validate_integrations(workspace: &Workspace) -> Result<()> {
)));
}
let org_integration = org_integrations.first().unwrap();
if org_integration.get_integration() != "docker" {
return Err(Error::InvalidIntegrations(format!(
"origin integration '{}' not supported",
org_integration.get_integration()
)));
}
if org_integration.get_name() != "docker" {
return Err(Error::InvalidIntegrations(format!(
"origin integration name '{}' not supported",
org_integration.get_name()
)));
}

// TODO fn: use a struct and serde to do heavy lifting
let creds: JsonValue = match serde_json::from_str(org_integration.get_body()) {
Ok(json) => json,
Expand Down Expand Up @@ -202,14 +186,14 @@ pub fn docker_exporter_spec(workspace: &Workspace) -> DockerExporterSpec {
// above. As a result, Any panics that occur are most likely due to programmer error and not
// input validation.

let creds: JsonValue = serde_json::from_str(
workspace
.job
.get_integrations()
.first()
.expect("Origin integrations must not be empty")
.get_body(),
).expect("Origin integrations body must be JSON");
let origin_integration = workspace.job.get_integrations().first().expect(
"Origin integrations must not be empty",
);

let creds: JsonValue = serde_json::from_str(origin_integration.get_body()).expect(
"Origin integrations body must be JSON",
);

let opts: JsonValue = serde_json::from_str(
workspace
.job
Expand All @@ -218,17 +202,10 @@ pub fn docker_exporter_spec(workspace: &Workspace) -> DockerExporterSpec {
.expect("Project integrations must not be empty")
.get_body(),
).expect("Project integrations body must be JSON");
let custom_tag = match opts.get("custom_tag") {
Some(val) => {
let val = val.as_str().expect("custom_tag value is a string");
if val.is_empty() {
None
} else {
Some(val.to_string())
}
}
None => None,
};

let custom_tag = get_optional_args(&opts, String::from("custom_tag"));
let registry_url = get_optional_args(&creds, String::from("registry_url"));
let registry_type = origin_integration.get_integration().to_string();

DockerExporterSpec {
username: creds
Expand All @@ -243,6 +220,8 @@ pub fn docker_exporter_spec(workspace: &Workspace) -> DockerExporterSpec {
.as_str()
.expect("password value is a string")
.to_string(),
registry_type: registry_type,
registry_url: registry_url,
docker_hub_repo_name: opts.get("docker_hub_repo_name")
.expect("docker_hub_repo_name key is present")
.as_str()
Expand All @@ -263,3 +242,17 @@ pub fn docker_exporter_spec(workspace: &Workspace) -> DockerExporterSpec {
custom_tag: custom_tag,
}
}

fn get_optional_args(opts: &JsonValue, arg: String) -> Option<String> {
match opts.get(arg) {
Some(key) => {
let key = key.as_str().unwrap_or("");
if key.is_empty() {
None
} else {
Some(key.to_string())
}
}
None => None,
}
}
2 changes: 1 addition & 1 deletion components/core/src/fs.rs
Expand Up @@ -336,7 +336,7 @@ pub fn resolve_cmd_in_pkg(program: &str, ident_str: &str) -> PathBuf {
}
Err(err) => {
panic!(format!(
"Package installation for '{}' not found! This is required for the \
"Package installation for '{}' not found on disk! This is required for the \
proper operation of this program (Err: {:?})",
&ident,
err
Expand Down