Skip to content

Commit

Permalink
Add GitHub Actions workflow ci.yaml (#34)
Browse files Browse the repository at this point in the history
Address compiler warnings given by `cargo check` or `cargo build`.

Address coding style issues given by `cargo fmt`.

Address issues given by linter, `cargo clippy`.

  * Remove unnecessary `return`.
  * Remove unnecessary `to_string`.
  * Remove comparison of `bool` with `true`/`false`.
  * Remove unnecessary references.
  * Remove redundant use `tokio`.
  * Remove unnecessary `let` binding.
  * Remove empty strings in `println!()`.
  * Use `vec![]` macro instead of pushing values to a mutable `Vec`.
  * Use `&str` instead of `&String` to avoid creating a new object.

Add new GitHub Actions workflow `ci.yaml`, which runs `cargo fmt`,
`cargo build`, `cargo test`, and `cargo clippy`.

Add GitHub CI status banner in `README.md`.

## Testing done

`cargo test`, `cargo fmt`, `cargo clippy` passed.
  • Loading branch information
dongsupark committed Feb 21, 2024
1 parent 3068896 commit d19b788
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 65 deletions.
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)

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

0 comments on commit d19b788

Please sign in to comment.