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 GitHub Actions workflow ci.yaml #34

Merged
merged 7 commits into from
Feb 21, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: "Run CI"
on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
build-test:
name: Build and test azure-provisioning-agent
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- run: rustup component add rustfmt
- name: Rustfmt Check
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all --check
- name: Build azure-provisioning-agent
uses: actions-rs/cargo@v1
with:
command: build
args: --verbose
- name: Run unit tests
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose
- name: Run clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --verbose -- --deny warnings
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ When you submit a pull request, a CLA-bot will automatically determine whether y
to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the
instructions provided by the bot. You will only need to do this once across all repositories using our CLA.

For each pull request, CI automatically runs unit tests by running `cargo test`, and also checks for coding styles and lints by running `cargo fmt` and `cargo clippy`. So please make sure that the all steps pass with the changes you made, `test`, `fmt`, and `clippy`, to avoid making CI fail with such issues.

This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
26 changes: 25 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,29 @@ build-all:
@echo ""
@cargo build --all

tests: build-all
@echo ""
@echo "**********************************"
@echo "* Unit testing"
@echo "**********************************"
@echo ""
@cargo test --all --verbose

e2e-test: build-all
@./tests/functional_tests.sh
@./tests/functional_tests.sh

fmt:
@echo ""
@echo "**********************************"
@echo "* Formatting"
@echo "**********************************"
@echo ""
@cargo fmt --all --check

clippy:
@echo ""
@echo "**********************************"
@echo "* Linting with clippy"
@echo "**********************************"
@echo ""
@cargo clippy --verbose -- --deny warnings
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Azure Provisioning Agent

[![Github CI](https://github.com/Azure/azure-provisioning-agent/actions/workflows/ci.yaml/badge.svg)](https://github.com/Azure/azure-provisioning-agent/actions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add some note to README to indicate that all PRs should run cargo fmt, cargo clippy, and cargo tests before submission, otherwise CI will fail and merging will be blocked.
Better yet, we can add some target to the Makefile such as "make tests", "make lint", "make format" to assist with invoking the proper cargo steps during development/submitting PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added notes to CONTRIBUTING.md.
Added makefile targets.


A guest agent implementation for provisioning Linux VMs on Azure.

The agent configures Linux guests from provisioning metadata.
Expand Down
16 changes: 7 additions & 9 deletions src/distro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl Distribution for Distributions {
home_path.push_str(username);

match Command::new("useradd")
.arg(username.to_string())
.arg(username)
.arg("--comment")
.arg(
"Provisioning agent created this user based on username provided in IMDS",
Expand All @@ -46,10 +46,10 @@ impl Distribution for Distributions {
Err(err) => return Err(err.to_string()),
};

if password.is_empty() == true {
if password.is_empty() {
match Command::new("passwd")
.arg("-d")
.arg(username.to_string())
.arg(username)
.status()
{
Ok(status_code) => {
Expand Down Expand Up @@ -88,7 +88,7 @@ impl Distribution for Distributions {
}
}

return Ok(0);
Ok(0)
}
}
}
Expand All @@ -100,11 +100,9 @@ impl Distribution for Distributions {
.arg(hostname)
.status()
{
Ok(status_code) => {
return Ok(status_code.code().unwrap_or(1))
}
Err(err) => return Err(err.to_string()),
};
Ok(status_code) => Ok(status_code.code().unwrap_or(1)),
Err(err) => Err(err.to_string()),
}
}
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/goalstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub async fn get_goalstate() -> Result<Goalstate, Box<dyn std::error::Error>> {

println!("Get request failed with status code: {}", response.status());

return Err(Box::from("Failed Get Call"));
Err(Box::from("Failed Get Call"))
}

pub async fn report_health(
Expand Down Expand Up @@ -102,7 +102,7 @@ pub async fn report_health(
response.status()
);

return Err(Box::from("Failed Post Call"));
Err(Box::from("Failed Post Call"))
}

fn build_report_health_file(goalstate: Goalstate) -> String {
Expand All @@ -127,15 +127,14 @@ fn build_report_health_file(goalstate: Goalstate) -> String {
post_request.replace("$GOAL_STATE_INCARNATION", &goalstate.incarnation);
let post_request = post_request
.replace("$CONTAINER_ID", &goalstate.container.container_id);
let post_request = post_request.replace(
post_request.replace(
"$INSTANCE_ID",
&goalstate
.container
.role_instance_list
.role_instance
.instance_id,
);
return post_request;
)
}

#[cfg(test)]
Expand Down
6 changes: 3 additions & 3 deletions src/imds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub async fn query_imds() -> Result<String, Box<dyn std::error::Error>> {
);
println!("{:?}", response.text().await);

return Err(Box::from("Failed Get Call"));
Err(Box::from("Failed Get Call"))
}

pub fn get_ssh_keys(
Expand Down Expand Up @@ -80,9 +80,9 @@ pub fn get_hostname(
}

pub fn get_provision_with_password(
imds_body: &String,
imds_body: &str,
) -> Result<bool, Box<dyn std::error::Error>> {
let data: Value = serde_json::from_str(&imds_body)
let data: Value = serde_json::from_str(imds_body)
.expect("Failed to parse the IMDS JSON.");

let provision_with_password = String::deserialize(
Expand Down
13 changes: 5 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

use tokio;

use lib::distro::{Distribution, Distributions};
use lib::{goalstate, imds, media, user};

#[tokio::main]
async fn main() {

let query_result = imds::query_imds().await;
let imds_body = match query_result {
Ok(imds_body) => imds_body,
Expand All @@ -24,13 +21,13 @@ async fn main() {
let username;
let mut password = "".to_owned();

if disable_authentication == false {
let _make_temp_directory_result = media::make_temp_directory().unwrap();
if !disable_authentication {
media::make_temp_directory().unwrap();

media::mount_media();

let ovf_body = media::read_ovf_env_to_string().unwrap();
let environment = media::parse_ovf_env(&ovf_body.as_str()).unwrap();
let environment = media::parse_ovf_env(ovf_body.as_str()).unwrap();

username = environment
.provisioning_section
Expand All @@ -41,7 +38,7 @@ async fn main() {
.linux_prov_conf_set
.password;

let authenticate_password = media::allow_password_authentication();
let _ = media::allow_password_authentication();

media::remove_media();
} else {
Expand Down Expand Up @@ -88,7 +85,7 @@ async fn main() {
};

let report_health_result = goalstate::report_health(vm_goalstate).await;
let _report_health = match report_health_result {
match report_health_result {
Ok(report_health) => report_health,
Err(_err) => return,
};
Expand Down
18 changes: 10 additions & 8 deletions src/media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use std::io::Write;
use std::os::unix::fs::PermissionsExt;
use std::process::Command;


use serde::Deserialize;
use serde_xml_rs::from_str;

Expand Down Expand Up @@ -92,13 +91,13 @@ pub fn remove_media() {
pub fn make_temp_directory() -> Result<(), Box<dyn std::error::Error>> {
let file_path = "/run/azure-provisioning-agent/tmp/";

create_dir_all(file_path.clone())?;
create_dir_all(file_path)?;

let metadata = fs::metadata(&file_path).unwrap();
let metadata = fs::metadata(file_path).unwrap();
let permissions = metadata.permissions();
let mut new_permissions = permissions.clone();
new_permissions.set_mode(0o700);
fs::set_permissions(&file_path, new_permissions).unwrap();
fs::set_permissions(file_path, new_permissions).unwrap();

Ok(())
}
Expand All @@ -116,7 +115,7 @@ pub fn read_ovf_env_to_string() -> Result<String, Box<dyn std::error::Error>> {
pub fn parse_ovf_env(
ovf_body: &str,
) -> Result<Environment, Box<dyn std::error::Error>> {
let environment: Environment = from_str(&ovf_body)?;
let environment: Environment = from_str(ovf_body)?;

if environment
.provisioning_section
Expand All @@ -130,12 +129,15 @@ pub fn parse_ovf_env(
Ok(environment)
}

pub fn allow_password_authentication() -> Result<(), Box<dyn std::error::Error>>{
pub fn allow_password_authentication() -> Result<(), Box<dyn std::error::Error>>
{
let file_path = "/etc/ssh/sshd_config.d/40-azure-provisioning-agent.conf";
let password_authentication = "PasswordAuthentication yes";

let mut file = File::create(file_path).expect("Unable to create sshd_config file.");
file.write_all(password_authentication.as_bytes()).expect("Unable to write to sshd_config file.");
let mut file =
File::create(file_path).expect("Unable to create sshd_config file.");
file.write_all(password_authentication.as_bytes())
.expect("Unable to write to sshd_config file.");

let _restart_ssh = Command::new("systemctl")
.arg("restart")
Expand Down
9 changes: 4 additions & 5 deletions src/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,11 @@ pub async fn set_ssh_keys(
for key in keys {
writeln!(authorized_keys, "{}", key.key_data).unwrap();
}
let metadata = fs::metadata(&authorized_keys_path.clone()).unwrap();
let metadata = fs::metadata(authorized_keys_path.clone()).unwrap();
let permissions = metadata.permissions();
let mut new_permissions = permissions.clone();
new_permissions.set_mode(0o600);
fs::set_permissions(&authorized_keys_path.clone(), new_permissions)
.unwrap();
fs::set_permissions(authorized_keys_path.clone(), new_permissions).unwrap();

let uid_username = CString::new(username.clone()).unwrap();
let uid_passwd = unsafe { libc::getpwnam(uid_username.as_ptr()) };
Expand Down Expand Up @@ -58,12 +57,12 @@ pub async fn create_ssh_directory(

create_dir(file_path.clone())?;

let uid_username = CString::new(username.clone()).unwrap();
let uid_username = CString::new(username).unwrap();
let uid_passwd = unsafe { libc::getpwnam(uid_username.as_ptr()) };
let uid = unsafe { (*uid_passwd).pw_uid };
let new_uid = Uid::from_raw(uid);

let gid_groupname = CString::new(username.clone()).unwrap();
let gid_groupname = CString::new(username).unwrap();
let gid_group = unsafe { libc::getgrnam(gid_groupname.as_ptr()) };
let gid = unsafe { (*gid_group).gr_gid };
let new_gid = Gid::from_raw(gid);
Expand Down
Loading
Loading