├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── custom.md │ └── feature-request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto_assign.yml ├── dependabot.yml └── workflows │ ├── auto-assign.yml │ ├── check-size.yml │ ├── ci.yml │ ├── codeql-analysis.yml │ ├── compatibility-e2e.yml │ ├── docker.yml │ ├── e2e-nydus.yml │ ├── e2e-rate-limit.yml │ ├── e2e.yml │ ├── lint.yml │ ├── pr-labels.yml │ ├── release.yml │ ├── scorecards.yml │ └── stale.yml ├── .gitignore ├── .gitmodules ├── .golangci.yml ├── .goreleaser.yml ├── .markdownlint.yml ├── ADOPTERS.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── GOVERNANCE.md ├── LICENSE ├── MAINTAINERS.md ├── Makefile ├── OWNERS.md ├── README.md ├── SECURITY.md ├── api ├── README.md └── manager │ ├── docs.go │ ├── swagger.json │ └── swagger.yaml ├── build ├── images │ ├── base │ │ ├── Dockerfile │ │ └── README.md │ ├── dfdaemon │ │ └── Dockerfile │ ├── manager │ │ └── Dockerfile │ └── scheduler │ │ └── Dockerfile ├── package │ ├── docs │ │ ├── dfcache │ │ │ ├── dfcache-delete.1 │ │ │ ├── dfcache-doc.1 │ │ │ ├── dfcache-export.1 │ │ │ ├── dfcache-import.1 │ │ │ ├── dfcache-plugin.1 │ │ │ ├── dfcache-stat.1 │ │ │ ├── dfcache-version.1 │ │ │ ├── dfcache.1 │ │ │ ├── dfcache.md │ │ │ ├── dfcache_delete.md │ │ │ ├── dfcache_doc.md │ │ │ ├── dfcache_export.md │ │ │ ├── dfcache_import.md │ │ │ ├── dfcache_plugin.md │ │ │ ├── dfcache_stat.md │ │ │ └── dfcache_version.md │ │ ├── dfget.1 │ │ ├── dfget.1.md │ │ └── dfstore │ │ │ ├── dfstore-copy.1 │ │ │ ├── dfstore-remove.1 │ │ │ ├── dfstore-version.1 │ │ │ ├── dfstore.1 │ │ │ ├── dfstore.md │ │ │ ├── dfstore_copy.md │ │ │ ├── dfstore_remove.md │ │ │ └── dfstore_version.md │ └── nfpm │ │ ├── config │ │ └── dfget.yaml │ │ ├── dfcache.yaml │ │ ├── dfget-postinstall.sh │ │ ├── dfget-postremove.sh │ │ ├── dfget-preinstall.sh │ │ ├── dfget-preremove.sh │ │ ├── dfget.yaml │ │ ├── dfstore.yaml │ │ └── systemd │ │ ├── dfget-daemon.service │ │ ├── dfget-daemon.service.d │ │ ├── CPUQuota.conf │ │ ├── CPUShares.conf │ │ └── MemoryLimit.conf │ │ └── fix.dfget-daemon.cpuset.sh └── plugin-builder │ ├── Dockerfile │ ├── build.sh │ └── images │ ├── dfdaemon │ └── Dockerfile │ ├── manager │ └── Dockerfile │ └── scheduler │ └── Dockerfile ├── client ├── config │ ├── constants.go │ ├── constants_otel.go │ ├── deprecated.go │ ├── dfcache.go │ ├── dfget.go │ ├── dfget_darwin.go │ ├── dfget_linux.go │ ├── dfget_test.go │ ├── dfstore.go │ ├── dfstore_test.go │ ├── dynconfig.go │ ├── dynconfig_local.go │ ├── dynconfig_local_test.go │ ├── dynconfig_manager.go │ ├── dynconfig_manager_test.go │ ├── dynconfig_test.go │ ├── fixme.go │ ├── flags.go │ ├── headers.go │ ├── mocks │ │ └── dynconfig_mock.go │ ├── peerhost.go │ ├── peerhost_darwin.go │ ├── peerhost_linux.go │ ├── peerhost_test.go │ └── testdata │ │ ├── certs │ │ ├── ca.crt │ │ ├── ca.key │ │ ├── sca.crt │ │ └── sca.key │ │ └── config │ │ ├── daemon.yaml │ │ └── proxy.yaml ├── daemon │ ├── announcer │ │ ├── announcer.go │ │ ├── announcer_test.go │ │ └── mocks │ │ │ └── announcer_mock.go │ ├── daemon.go │ ├── daemon_linux.go │ ├── daemon_stub.go │ ├── gc │ │ └── gc_manager.go │ ├── metrics │ │ ├── metrics.go │ │ └── metrics_test.go │ ├── objectstorage │ │ ├── mocks │ │ │ └── objectstorage_mock.go │ │ ├── objectstorage.go │ │ └── types.go │ ├── peer │ │ ├── peerid_generator.go │ │ ├── peertask_bitmap.go │ │ ├── peertask_conductor.go │ │ ├── peertask_dummy.go │ │ ├── peertask_file.go │ │ ├── peertask_manager.go │ │ ├── peertask_manager_mock.go │ │ ├── peertask_manager_test.go │ │ ├── peertask_piecetask_synchronizer.go │ │ ├── peertask_piecetask_synchronizer_test.go │ │ ├── peertask_reuse.go │ │ ├── peertask_reuse_test.go │ │ ├── peertask_seed.go │ │ ├── peertask_stream.go │ │ ├── peertask_stream_backsource_partial_test.go │ │ ├── peertask_stream_resume_test.go │ │ ├── peertask_test.go │ │ ├── piece_broker.go │ │ ├── piece_broker_test.go │ │ ├── piece_dispatcher.go │ │ ├── piece_downloader.go │ │ ├── piece_downloader_mock.go │ │ ├── piece_downloader_test.go │ │ ├── piece_manager.go │ │ ├── piece_manager_mock.go │ │ ├── piece_manager_test.go │ │ ├── traffic_shaper.go │ │ └── traffic_shaper_test.go │ ├── pex │ │ ├── delegate.go │ │ ├── member_manager.go │ │ ├── member_pool.go │ │ ├── peer_exchange.go │ │ ├── peer_exchange_rpc.go │ │ ├── peer_pool.go │ │ ├── seed_peer.go │ │ ├── seed_peer_test.go │ │ └── types.go │ ├── proxy │ │ ├── cert.go │ │ ├── mocks │ │ │ └── proxy_manager_mock.go │ │ ├── proxy.go │ │ ├── proxy_manager.go │ │ ├── proxy_sni.go │ │ ├── proxy_test.go │ │ ├── proxy_writter.go │ │ └── reverse_proxy.go │ ├── rpcserver │ │ ├── mocks │ │ │ └── rpcserver_mock.go │ │ ├── peer_exchange.go │ │ ├── rpcserver.go │ │ ├── rpcserver_test.go │ │ ├── seeder.go │ │ ├── seeder_test.go │ │ └── subscriber.go │ ├── storage │ │ ├── const.go │ │ ├── keepalive.go │ │ ├── local_storage.go │ │ ├── local_storage_subtask.go │ │ ├── local_storage_test.go │ │ ├── metadata.go │ │ ├── mocks │ │ │ └── stroage_manager_mock.go │ │ └── storage_manager.go │ ├── test │ │ ├── common.go │ │ └── testdata │ │ │ └── go.html │ ├── transport │ │ ├── transport.go │ │ └── transport_test.go │ └── upload │ │ ├── mocks │ │ └── upload_manager_mock.go │ │ ├── types.go │ │ ├── upload_manager.go │ │ └── upload_manager_test.go ├── dfcache │ └── dfcache.go ├── dfget │ ├── dfget.go │ └── dfget_test.go ├── dfstore │ ├── dfstore.go │ └── mocks │ │ └── dfstore_mock.go └── util │ ├── keepalive.go │ ├── mocks │ └── keepalive_mock.go │ └── types.go ├── cmd ├── dependency │ ├── base │ │ └── option.go │ ├── dependency.go │ ├── doc_cmd.go │ ├── plugin_cmd.go │ └── version_cmd.go ├── dfcache │ ├── cmd │ │ ├── delete.go │ │ ├── export.go │ │ ├── import.go │ │ ├── root.go │ │ └── stat.go │ └── main.go ├── dfget │ ├── cmd │ │ ├── daemon.go │ │ └── root.go │ └── main.go ├── dfstore │ ├── cmd │ │ ├── copy.go │ │ ├── remove.go │ │ ├── root.go │ │ └── util.go │ └── main.go ├── manager │ ├── cmd │ │ └── root.go │ └── main.go └── scheduler │ ├── cmd │ └── root.go │ └── main.go ├── codecov.yml ├── deploy └── docker-compose │ ├── README.md │ ├── docker-compose.yaml │ ├── run.sh │ └── template │ ├── client.template.yaml │ ├── manager.template.yaml │ ├── scheduler.template.yaml │ └── seed-client.template.yaml ├── docs ├── README.md ├── images │ ├── arch.png │ ├── community │ │ └── dingtalk-group.jpeg │ └── logo │ │ ├── dragonfly-linear.png │ │ ├── dragonfly-linear.svg │ │ ├── dragonfly-vertical.png │ │ └── dragonfly.svg └── security │ └── dragonfly-comprehensive-report-2023.pdf ├── go.mod ├── go.sum ├── hack ├── build.sh ├── ca │ ├── .gitignore │ ├── gen-manager-ca.sh │ └── gen-root-ca.sh ├── docker-build.sh ├── docker-push.sh ├── env.sh ├── gen-containerd-hosts.sh ├── install-e2e-test.sh ├── install.sh ├── kind-load.sh ├── markdownlint.sh └── update-version-gorelease.sh ├── internal ├── dferrors │ └── error.go ├── dflog │ ├── logcore.go │ ├── logger.go │ ├── loginit.go │ └── signal.go ├── dfplugin │ └── dfplugin.go ├── dynconfig │ ├── dynconfig.go │ ├── dynconfig_test.go │ ├── manager_client.go │ ├── mocks │ │ ├── dynconfig_mock.go │ │ └── manager_client_mock.go │ └── testdata │ │ └── dynconfig.json ├── job │ ├── constants.go │ ├── job.go │ ├── job_test.go │ ├── logger.go │ ├── queue.go │ ├── queue_test.go │ └── types.go ├── ratelimiter │ ├── distributed_ratelimiter.go │ └── job_ratelimiter.go └── util │ ├── util.go │ └── util_test.go ├── manager ├── auth │ └── oauth │ │ ├── github.go │ │ ├── google.go │ │ ├── mocks │ │ └── oauth_mock.go │ │ └── oauth.go ├── cache │ └── cache.go ├── config │ ├── config.go │ ├── config_test.go │ ├── constant_otel.go │ ├── constants.go │ └── testdata │ │ ├── ca.crt │ │ ├── ca.key │ │ └── manager.yaml ├── database │ ├── cacher.go │ ├── database.go │ ├── mysql.go │ └── postgres.go ├── dist │ └── .gitkeep ├── gc │ ├── audit.go │ ├── job.go │ └── recorder.go ├── handlers │ ├── application.go │ ├── application_test.go │ ├── audit.go │ ├── audit_test.go │ ├── bucket.go │ ├── bucket_test.go │ ├── cluster.go │ ├── cluster_test.go │ ├── config.go │ ├── config_test.go │ ├── handlers.go │ ├── handlers_test.go │ ├── health.go │ ├── health_test.go │ ├── job.go │ ├── job_test.go │ ├── oauth.go │ ├── oauth_test.go │ ├── peer.go │ ├── peer_test.go │ ├── permission.go │ ├── permission_test.go │ ├── persistent_cache_task.go │ ├── persistent_cache_task_test.go │ ├── personal_access_token.go │ ├── personal_access_token_test.go │ ├── preheat.go │ ├── preheat_test.go │ ├── role.go │ ├── role_test.go │ ├── scheduler.go │ ├── scheduler_cluster.go │ ├── scheduler_cluster_test.go │ ├── scheduler_feature.go │ ├── scheduler_test.go │ ├── seed_peer.go │ ├── seed_peer_cluster.go │ ├── seed_peer_cluster_test.go │ ├── seed_peer_test.go │ ├── user.go │ └── user_test.go ├── job │ ├── job.go │ ├── mocks │ │ ├── gc_mock.go │ │ ├── preheat_mock.go │ │ ├── sync_peers_mock.go │ │ └── task_mock.go │ ├── preheat.go │ ├── preheat_test.go │ ├── sync_peers.go │ ├── task.go │ ├── task_test.go │ └── types.go ├── manager.go ├── metrics │ ├── metrics.go │ └── metrics_test.go ├── middlewares │ ├── audit.go │ ├── cors.go │ ├── error.go │ ├── jwt.go │ ├── personal_access_token.go │ ├── ratelimiter.go │ ├── rbac.go │ └── server.go ├── models │ ├── application.go │ ├── audit.go │ ├── casbin_rule.go │ ├── config.go │ ├── job.go │ ├── models.go │ ├── oauth.go │ ├── peer.go │ ├── personal_access_token.go │ ├── scheduler.go │ ├── scheduler_cluster.go │ ├── seed_peer.go │ ├── seed_peer_cluster.go │ └── user.go ├── permission │ └── rbac │ │ ├── rbac.go │ │ └── rbac_test.go ├── router │ └── router.go ├── rpcserver │ ├── manager_server_v1.go │ ├── manager_server_v2.go │ └── rpcserver.go ├── searcher │ ├── mocks │ │ └── searcher_mock.go │ ├── plugin.go │ ├── plugin_test.go │ ├── searcher.go │ ├── searcher_test.go │ └── testdata │ │ ├── main.go │ │ └── plugin │ │ └── searcher.go ├── service │ ├── application.go │ ├── audit.go │ ├── bucket.go │ ├── cluster.go │ ├── config.go │ ├── job.go │ ├── mocks │ │ └── service_mock.go │ ├── oauth.go │ ├── peer.go │ ├── permission.go │ ├── persistent_cache_task.go │ ├── personal_access_token.go │ ├── preheat.go │ ├── role.go │ ├── scheduler.go │ ├── scheduler_cluster.go │ ├── scheduler_feature.go │ ├── seed_peer.go │ ├── seed_peer_cluster.go │ ├── service.go │ └── user.go └── types │ ├── application.go │ ├── audit.go │ ├── bucket.go │ ├── cluster.go │ ├── config.go │ ├── job.go │ ├── oauth.go │ ├── peer.go │ ├── persional_access_token.go │ ├── persistent_cache_task.go │ ├── preheat.go │ ├── role.go │ ├── scheduler.go │ ├── scheduler_cluster.go │ ├── scheduler_feature.go │ ├── seed_peer.go │ ├── seed_peer_cluster.go │ └── user.go ├── pkg ├── balancer │ └── consistent_hashing.go ├── cache │ ├── cache.go │ ├── cache_mock.go │ └── cache_test.go ├── container │ ├── ring │ │ ├── queue.go │ │ ├── queue_test.go │ │ ├── random.go │ │ └── sequence.go │ └── set │ │ ├── mocks │ │ ├── safe_set_mock.go │ │ └── set_mock.go │ │ ├── safe_set.go │ │ ├── safe_set_test.go │ │ ├── set.go │ │ └── set_test.go ├── dfnet │ └── dfnet.go ├── dfpath │ ├── dfpath.go │ ├── dfpath_darwin.go │ ├── dfpath_linux.go │ ├── dfpath_test.go │ └── mocks │ │ └── dfpath_mock.go ├── digest │ ├── digest.go │ ├── digest_reader.go │ ├── digest_reader_test.go │ ├── digest_test.go │ └── mocks │ │ └── digest_reader_mock.go ├── gc │ ├── gc.go │ ├── gc_mock.go │ ├── gc_test.go │ ├── logger.go │ ├── logger_mock.go │ ├── runner_mock.go │ └── task.go ├── graph │ ├── dag │ │ ├── dag.go │ │ ├── dag_test.go │ │ ├── mocks │ │ │ └── dag_mock.go │ │ ├── vertex.go │ │ └── vertex_test.go │ └── dg │ │ ├── dg.go │ │ ├── dg_test.go │ │ ├── mocks │ │ └── dg_mock.go │ │ ├── vertex.go │ │ └── vertex_test.go ├── idgen │ ├── host_id.go │ ├── host_id_test.go │ ├── peer_id.go │ ├── peer_id_test.go │ ├── task_id.go │ └── task_id_test.go ├── io │ ├── multi_readcloser.go │ └── multi_readcloser_test.go ├── log │ └── log.go ├── math │ ├── math.go │ └── rand.go ├── net │ ├── fqdn │ │ ├── fqdn.go │ │ └── fqdn_test.go │ ├── http │ │ ├── header.go │ │ ├── http.go │ │ ├── http_test.go │ │ ├── range.go │ │ └── range_test.go │ ├── ip │ │ ├── ip.go │ │ ├── ip_test.go │ │ ├── ipv4.go │ │ ├── ipv4_test.go │ │ ├── ipv6.go │ │ └── ipv6_test.go │ ├── ping │ │ ├── ping.go │ │ └── ping_test.go │ └── url │ │ ├── url.go │ │ └── url_test.go ├── objectstorage │ ├── constants.go │ ├── mocks │ │ └── objectstorage_mock.go │ ├── objectstorage.go │ ├── obs.go │ ├── oss.go │ └── s3.go ├── os │ └── user │ │ └── user.go ├── redis │ ├── proxy.go │ ├── redis.go │ ├── redis_logger.go │ └── redis_test.go ├── resolver │ ├── scheduler_resolver.go │ └── seed_peer_resolver.go ├── retry │ └── retry.go ├── rpc │ ├── cdnsystem │ │ ├── client │ │ │ ├── client.go │ │ │ └── mocks │ │ │ │ └── client_mock.go │ │ └── server │ │ │ └── server.go │ ├── common │ │ └── common.go │ ├── credential.go │ ├── dfdaemon │ │ ├── client │ │ │ ├── client_v1.go │ │ │ ├── client_v2.go │ │ │ ├── constants.go │ │ │ └── mocks │ │ │ │ ├── client_v1_mock.go │ │ │ │ └── client_v2_mock.go │ │ └── server │ │ │ └── server.go │ ├── health │ │ └── client │ │ │ ├── client.go │ │ │ └── mocks │ │ │ └── client_mock.go │ ├── interceptor.go │ ├── manager │ │ ├── client │ │ │ ├── client_v1.go │ │ │ ├── client_v2.go │ │ │ ├── constants.go │ │ │ └── mocks │ │ │ │ ├── client_v1_mock.go │ │ │ │ └── client_v2_mock.go │ │ └── server │ │ │ └── server.go │ ├── scheduler │ │ ├── client │ │ │ ├── client_v1.go │ │ │ ├── client_v2.go │ │ │ ├── constants.go │ │ │ └── mocks │ │ │ │ ├── client_v1_mock.go │ │ │ │ └── client_v2_mock.go │ │ └── server │ │ │ └── server.go │ ├── server_listen.go │ └── vsock.go ├── safe │ └── safe.go ├── slices │ ├── slices.go │ └── slices_test.go ├── source │ ├── clients │ │ ├── example │ │ │ └── dfs.go │ │ ├── gsprotocol │ │ │ ├── gs_source_client.go │ │ │ └── gs_source_client_test.go │ │ ├── hdfsprotocol │ │ │ └── hdfs_source_client.go │ │ ├── httpprotocol │ │ │ ├── header.go │ │ │ ├── http_source_client.go │ │ │ └── http_source_client_test.go │ │ ├── orasprotocol │ │ │ └── oras_source_client.go │ │ ├── ossprotocol │ │ │ └── oss_source_client.go │ │ └── s3protocol │ │ │ └── s3_source_client.go │ ├── header.go │ ├── header_test.go │ ├── list_metadata.go │ ├── loader │ │ ├── dfs.go.example │ │ ├── gs.go │ │ ├── hdfs.go │ │ ├── http.go │ │ ├── oras.go │ │ ├── oss.go │ │ └── s3.go │ ├── metadata.go │ ├── metrics.go │ ├── mocks │ │ └── mock_source_client.go │ ├── plugin.go │ ├── plugin_test.go │ ├── request.go │ ├── request_fixture.go │ ├── request_test.go │ ├── response.go │ ├── source_client.go │ ├── source_client_builder.go │ ├── testdata │ │ ├── main.go │ │ └── plugin │ │ │ └── dfs.go │ └── transport_option.go ├── storage │ ├── piece.go │ ├── piece_test.go │ ├── stat_task.go │ └── stat_task_test.go ├── strings │ ├── strings.go │ └── strings_test.go ├── structure │ ├── structure.go │ └── structure_test.go ├── time │ ├── time.go │ └── time_test.go ├── types │ ├── constants.go │ └── types.go └── unit │ ├── byte.go │ └── byte_test.go ├── scheduler ├── announcer │ ├── announcer.go │ ├── announcer_test.go │ └── mocks │ │ └── announcer_mock.go ├── config │ ├── config.go │ ├── config_test.go │ ├── constants.go │ ├── dynconfig.go │ ├── dynconfig_test.go │ ├── mocks │ │ └── dynconfig_mock.go │ └── testdata │ │ ├── ca.crt │ │ └── scheduler.yaml ├── job │ ├── job.go │ └── mocks │ │ └── job_mock.go ├── metrics │ ├── metrics.go │ └── metrics_test.go ├── resource │ ├── persistentcache │ │ ├── host.go │ │ ├── host_manager.go │ │ ├── host_manager_mock.go │ │ ├── host_manager_test.go │ │ ├── host_test.go │ │ ├── peer.go │ │ ├── peer_manager.go │ │ ├── peer_manager_mock.go │ │ ├── peer_manager_test.go │ │ ├── peer_test.go │ │ ├── resource.go │ │ ├── resource_mock.go │ │ ├── task.go │ │ ├── task_manager.go │ │ ├── task_manager_mock.go │ │ ├── task_manager_test.go │ │ └── task_test.go │ └── standard │ │ ├── host.go │ │ ├── host_manager.go │ │ ├── host_manager_mock.go │ │ ├── host_manager_test.go │ │ ├── host_test.go │ │ ├── peer.go │ │ ├── peer_manager.go │ │ ├── peer_manager_mock.go │ │ ├── peer_manager_test.go │ │ ├── peer_test.go │ │ ├── piece.go │ │ ├── piece_test.go │ │ ├── resource.go │ │ ├── resource_mock.go │ │ ├── resource_test.go │ │ ├── seed_peer.go │ │ ├── seed_peer_client.go │ │ ├── seed_peer_client_mock.go │ │ ├── seed_peer_client_test.go │ │ ├── seed_peer_mock.go │ │ ├── seed_peer_test.go │ │ ├── task.go │ │ ├── task_manager.go │ │ ├── task_manager_mock.go │ │ ├── task_manager_test.go │ │ └── task_test.go ├── rpcserver │ ├── rpcserver.go │ ├── rpcserver_test.go │ ├── scheduler_server_v1.go │ └── scheduler_server_v2.go ├── scheduler.go ├── scheduling │ ├── evaluator │ │ ├── evaluator.go │ │ ├── evaluator_base.go │ │ ├── evaluator_base_test.go │ │ ├── evaluator_test.go │ │ ├── plugin.go │ │ ├── plugin_test.go │ │ └── testdata │ │ │ ├── main.go │ │ │ └── plugin │ │ │ └── evaluator.go │ ├── mocks │ │ └── scheduling_mock.go │ ├── scheduling.go │ └── scheduling_test.go └── service │ ├── service_v1.go │ ├── service_v1_test.go │ ├── service_v2.go │ └── service_v2_test.go ├── test ├── README.md ├── e2e │ ├── concurrency_test.go │ ├── containerd_test.go │ ├── dfcache_test.go │ ├── dfget_test.go │ ├── e2e_test.go │ ├── host_test.go │ ├── manager │ │ ├── job.go │ │ ├── preheat.go │ │ └── task.go │ ├── proxy_test.go │ ├── rate_limit_test.go │ └── util │ │ ├── artifact.go │ │ ├── constants.go │ │ ├── dufs.go │ │ ├── exec.go │ │ ├── file.go │ │ ├── file_server.go │ │ └── task.go └── testdata │ ├── charts │ ├── config-nydus.yaml │ ├── config-rate-limit.yaml │ └── config.yaml │ ├── containerd │ └── config.toml │ ├── k8s │ ├── dufs.yaml │ └── nydus.yaml │ └── kind │ └── config.yaml └── version ├── platform_darwin.go ├── platform_linux.go └── version.go /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # A CODEOWNERS file uses a pattern that follows the same rules used in gitignore files. 2 | # The pattern is followed by one or more GitHub usernames or team names using the 3 | # standard @username or @org/team-name format. You can also refer to a user by an 4 | # email address that has been added to their GitHub account, for example user@example.com 5 | 6 | * @dragonflyoss/dragonfly2-reviewers 7 | .github @dragonflyoss/dragonfly2-maintainers 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug for dragonfly 4 | labels: bug 5 | 6 | --- 7 | 8 | ### Bug report: 9 | 10 | 11 | 12 | ### Expected behavior: 13 | 14 | 15 | 16 | ### How to reproduce it: 17 | 18 | 19 | 20 | ### Environment: 21 | 22 | - Dragonfly version: 23 | - OS: 24 | - Kernel (e.g. `uname -a`): 25 | - Others: 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Custom issue template for dragonfly 4 | 5 | --- 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Request a new feature for dragonfly 4 | labels: enhancement 5 | 6 | --- 7 | 8 | ### Feature request: 9 | 10 | 11 | 12 | ### Use case: 13 | 14 | 15 | 16 | ### UI Example: 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Description 4 | 5 | 6 | 7 | ## Related Issue 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## Motivation and Context 15 | 16 | 17 | 18 | ## Screenshots (if appropriate) 19 | 20 | ## Types of changes 21 | 22 | 23 | 24 | - [ ] Bug fix (non-breaking change which fixes an issue) 25 | - [ ] New feature (non-breaking change which adds functionality) 26 | - [ ] Breaking change (fix or feature that would cause existing functionality to change) 27 | - [ ] Documentation Update (if none of the other choices apply) 28 | 29 | ## Checklist 30 | 31 | 32 | 33 | 34 | - [ ] My change requires a change to the documentation. 35 | - [ ] I have updated the documentation accordingly. 36 | - [ ] I have read the **CONTRIBUTING** document. 37 | - [ ] I have added tests to cover my changes. 38 | -------------------------------------------------------------------------------- /.github/auto_assign.yml: -------------------------------------------------------------------------------- 1 | # Set to true to add reviewers to pull requests 2 | addReviewers: false 3 | 4 | # Set to true to add assignees to pull requests 5 | addAssignees: true 6 | 7 | assignees: 8 | - gaius-qi 9 | - yxxhero 10 | - chlins 11 | - CormickKneey 12 | - jim3ma 13 | - hyy0322 14 | - xujihui1985 15 | 16 | numberOfAssignees: 3 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "gomod" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | - package-ecosystem: "github-actions" 8 | directory: "/" 9 | schedule: 10 | interval: "weekly" 11 | -------------------------------------------------------------------------------- /.github/workflows/auto-assign.yml: -------------------------------------------------------------------------------- 1 | name: "Auto Assign" 2 | 3 | on: 4 | pull_request_target: 5 | types: [opened, reopened, ready_for_review] 6 | 7 | permissions: 8 | pull-requests: write 9 | 10 | jobs: 11 | add-assignee: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: kentaro-m/auto-assign-action@7ae38e468e64dec0af17820972bc4915aa511ec2 15 | -------------------------------------------------------------------------------- /.github/workflows/check-size.yml: -------------------------------------------------------------------------------- 1 | name: Check Size 2 | 3 | on: 4 | push: 5 | branches: [main, release-*] 6 | pull_request: 7 | branches: [main, release-*] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | check_size: 14 | name: Check Size 15 | timeout-minutes: 10 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 20 | with: 21 | fetch-depth: 1 22 | 23 | - name: Check large files 24 | uses: actionsdesk/lfs-warning@e5f9a4c21f4bee104db7c0f23954dde59e5df909 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | with: 28 | filesizelimit: "1048576" 29 | exclusionPatterns: | 30 | deploy/helm-charts 31 | manager/console 32 | client-rs 33 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL Analysis 2 | 3 | on: 4 | push: 5 | branches: [main, release-*] 6 | paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**'] 7 | pull_request: 8 | branches: [main, release-*] 9 | paths-ignore: ['**.md', '**.png', '**.jpg', '**.svg', '**/docs/**'] 10 | schedule: 11 | - cron: '0 4 * * *' 12 | 13 | permissions: 14 | contents: read 15 | 16 | jobs: 17 | analyze: 18 | name: Analyze 19 | runs-on: ubuntu-latest 20 | 21 | permissions: 22 | security-events: write 23 | 24 | strategy: 25 | fail-fast: false 26 | matrix: 27 | language: [go] 28 | 29 | steps: 30 | - name: Checkout repository 31 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 32 | 33 | - name: Initialize CodeQL 34 | uses: github/codeql-action/init@ff0a06e83cb2de871e5a09832bc6a81e7276941f 35 | with: 36 | languages: ${{ matrix.language }} 37 | 38 | - name: Autobuild 39 | uses: github/codeql-action/autobuild@ff0a06e83cb2de871e5a09832bc6a81e7276941f 40 | 41 | - name: Perform CodeQL Analysis 42 | uses: github/codeql-action/analyze@ff0a06e83cb2de871e5a09832bc6a81e7276941f 43 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [main, release-*] 6 | pull_request: 7 | branches: [main, release-*] 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 30 17 | steps: 18 | - name: Checkout code 19 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 20 | with: 21 | fetch-depth: '0' 22 | 23 | - name: Golangci lint 24 | uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd 25 | with: 26 | version: v2.0 27 | 28 | - name: Markdown lint 29 | uses: docker://avtodev/markdown-lint:v1@sha256:6aeedc2f49138ce7a1cd0adffc1b1c0321b841dc2102408967d9301c031949ee 30 | with: 31 | config: '.markdownlint.yml' 32 | args: '**/*.md' 33 | ignore: 'deploy/helm-charts manager/console CHANGELOG.md build' 34 | -------------------------------------------------------------------------------- /.github/workflows/pr-labels.yml: -------------------------------------------------------------------------------- 1 | name: PR Label 2 | 3 | on: 4 | pull_request: 5 | types: [opened, labeled, unlabeled, synchronize] 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | classify: 12 | name: Classify PR 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: PR impact specified 16 | uses: mheap/github-action-required-labels@388fd6af37b34cdfe5a23b37060e763217e58b03 # v5.5 17 | with: 18 | mode: exactly 19 | count: 1 20 | labels: 'bug, enhancement, documentation, dependencies' 21 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Close stale issues and PRs 2 | 3 | on: 4 | workflow_dispatch: 5 | schedule: 6 | - cron: "0 0 * * *" 7 | 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 17 | id: stale 18 | with: 19 | delete-branch: true 20 | days-before-close: 7 21 | days-before-stale: 90 22 | days-before-pr-close: 7 23 | days-before-pr-stale: 120 24 | stale-issue-label: "stale" 25 | exempt-issue-labels: bug,wip,on-hold 26 | exempt-pr-labels: bug,wip,on-hold 27 | exempt-all-milestones: true 28 | stale-issue-message: 'This issue is stale because it has been open 90 days with no activity.' 29 | close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' 30 | stale-pr-message: 'This PR is stale because it has been open 120 days with no activity.' 31 | close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.' 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | 5 | # Test binary, built with `go test -c` 6 | *.test 7 | 8 | # Output of the go coverage tool, specifically when used with LiteIDE 9 | *.out 10 | 11 | # Dependency directories (remove the comment below to include it) 12 | vendor/ 13 | .idea 14 | .vscode 15 | .cache 16 | *.DS_Store 17 | target/ 18 | scheduler/test/misc 19 | manager/dist/* 20 | !manager/dist/.gitkeep 21 | .chglog 22 | 23 | # mysql 24 | mysql 25 | 26 | # vscode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | *.code-workspace 33 | 34 | # General 35 | .DS_Store 36 | .AppleDouble 37 | .LSOverride 38 | 39 | # Icon must end with two \r 40 | Icon 41 | 42 | 43 | # Thumbnails 44 | ._* 45 | 46 | # Files that might appear in the root of a volume 47 | .DocumentRevisions-V100 48 | .fseventsd 49 | .Spotlight-V100 50 | .TemporaryItems 51 | .Trashes 52 | .VolumeIcon.icns 53 | .com.apple.timemachine.donotpresent 54 | 55 | # Directories potentially created on remote AFP share 56 | .AppleDB 57 | .AppleDesktop 58 | Network Trash Folder 59 | Temporary Items 60 | .apdisk 61 | 62 | artifacts 63 | .run 64 | deploy/docker-compose/log 65 | deploy/docker-compose/config 66 | test/e2e/v1/*.log 67 | test/e2e/*.log 68 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deploy/helm-charts"] 2 | path = deploy/helm-charts 3 | url = https://github.com/dragonflyoss/helm-charts.git 4 | [submodule "manager/console"] 5 | path = manager/console 6 | url = https://github.com/dragonflyoss/console.git 7 | [submodule "client-rs"] 8 | path = client-rs 9 | url = https://github.com/dragonflyoss/client.git 10 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | run: 3 | modules-download-mode: readonly 4 | linters: 5 | default: none 6 | enable: 7 | - errcheck 8 | - goconst 9 | - gocyclo 10 | - govet 11 | - misspell 12 | - staticcheck 13 | settings: 14 | gocyclo: 15 | min-complexity: 100 16 | exclusions: 17 | generated: lax 18 | presets: 19 | - comments 20 | - common-false-positives 21 | - legacy 22 | - std-error-handling 23 | rules: 24 | - linters: 25 | - staticcheck 26 | text: 'SA1019:' 27 | paths: 28 | - third_party$ 29 | - builtin$ 30 | - examples$ 31 | issues: 32 | new: true 33 | formatters: 34 | enable: 35 | - gci 36 | - gofmt 37 | settings: 38 | gci: 39 | sections: 40 | - standard 41 | - default 42 | - prefix(d7y.io/api) 43 | - prefix(d7y.io/dragonfly/v2) 44 | exclusions: 45 | generated: lax 46 | paths: 47 | - third_party$ 48 | - builtin$ 49 | - examples$ 50 | 51 | output: 52 | formats: 53 | text: 54 | path: stdout 55 | print-linter-name: true 56 | print-issued-lines: true 57 | colors: true 58 | -------------------------------------------------------------------------------- /.markdownlint.yml: -------------------------------------------------------------------------------- 1 | MD010: false 2 | MD013: 3 | line_length: 120 4 | MD046: 5 | style: "fenced" 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Dragonfly Community Code of Conduct 2 | 3 | Please refer to the [community code of conduct](https://github.com/dragonflyoss/community/blob/master/CODE_OF_CONDUCT.md). 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Dragonfly 2 | 3 | Please refer to the [community contributing guide](https://github.com/dragonflyoss/community/blob/master/CONTRIBUTING.md). 4 | -------------------------------------------------------------------------------- /GOVERNANCE.md: -------------------------------------------------------------------------------- 1 | # Dragonfly Project Governance 2 | 3 | Please refer to the [community project governance](https://github.com/dragonflyoss/community/blob/master/GOVERNANCE.md). 4 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Please refer to the [community security policy](https://github.com/dragonflyoss/community/blob/master/SECURITY.md). 4 | -------------------------------------------------------------------------------- /api/README.md: -------------------------------------------------------------------------------- 1 | # Dragonfly V2 API 2 | 3 | We encourage users to experience Dragonfly in different ways. 4 | When doing this, there are three ways users 5 | could choose to interact with dragonfly mostly: 6 | 7 | * For end-users, command line tool `dfget`, `dfdaemon` is mostly used. 8 | * For developers, Dragonfly manager's raw API is 9 | the original thing they would make use of. 10 | For more details about API docs, please refer to [api.md](./manager/swagger.json). 11 | We should also keep it in mind that doc 12 | [apis.md](./manager/swagger.json) is automatically generated by 13 | [swagger2markup](https://github.com/Swagger2Markup/swagger2markup). 14 | Please **DO NOT** edit [api.md](./manager/swagger.json) directly. 15 | 16 | Directory `/api` mainly describes the second part **Dragonfly Manager's Raw API**. 17 | 18 | Currently, the description of swagger format is provided, 19 | which can be viewed in `manager`. 20 | It contains two format files of swagger, JSON and yaml. You can 21 | browse through relevant viewing tools to obtain the specific call method of API, 22 | or view online through the `/swagger/doc.json` endpoint of manager service. 23 | 24 | Through manager's API, you can integrate with your own services, 25 | so you can automatically manage dragonfly and improve the level of Devops. 26 | -------------------------------------------------------------------------------- /build/images/base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM quay.io/iovisor/bpftrace:v0.13.0 2 | 3 | ENV DEBIAN_FRONTEND noninteractive 4 | 5 | RUN apt-get update \ 6 | && apt-get install -y binutils bpfcc-tools curl dnsutils git iproute2 iputils-ping jq netcat socat tree vim wget \ 7 | && apt-get install -y openssh-client openssh-server \ 8 | && rm -rf /var/lib/apt/lists/* \ 9 | && mkdir -p /run/sshd 10 | 11 | ENV PATH=/go/bin:/usr/local/go/bin:$PATH 12 | 13 | ENV GOPATH=/go 14 | ENV GOLANG_VERSION 1.23.8 15 | ENV GOLANG_DOWNLOAD_URL https://go.dev/dl/go1.23.8.linux-amd64.tar.gz 16 | ENV GOLANG_DOWNLOAD_SHA256 000a5b1fca4f75895f78befeb2eecf10bfff3c428597f3f1e69133b63b911b02 17 | 18 | ARG GOPROXY 19 | 20 | RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ 21 | && echo "$GOLANG_DOWNLOAD_SHA256 golang.tar.gz" | sha256sum -c - \ 22 | && tar -C /usr/local -xzf golang.tar.gz \ 23 | && rm golang.tar.gz \ 24 | && go install github.com/go-delve/delve/cmd/dlv@v1.7.0 25 | -------------------------------------------------------------------------------- /build/images/base/README.md: -------------------------------------------------------------------------------- 1 | # Base image 2 | 3 | ## Base Image for Debugging 4 | 5 | ### Build Base Image 6 | 7 | ```shell 8 | docker build -t dragonflyoss/base:bpftrace-v0.13.0-go-v1.20.1 -f Dockerfile . 9 | ``` 10 | 11 | ### Run Debug Container 12 | 13 | ```shell 14 | BASE_IMAGE=dragonflyoss/base:bpftrace-v0.13.0-go-v1.20.1 15 | 16 | # run debug container 17 | docker run -ti -v /usr/src:/usr/src:ro \ 18 | -v /lib/modules/:/lib/modules:ro \ 19 | -v /sys/kernel/debug/:/sys/kernel/debug:rw \ 20 | --net=host --pid=host --privileged \ 21 | ${BASE_IMAGE} 22 | ``` 23 | 24 | ### Build Dragonfly Images 25 | 26 | ```shell 27 | # tags for condition compiling 28 | export GOTAGS="debug" 29 | # gcflags for dlv 30 | export GOGCFLAGS="all=-N -l" 31 | # base image 32 | export BASE_IMAGE=dragonflyoss/base:bpftrace-v0.13.0-go-v1.20.1 33 | 34 | make docker-build 35 | ``` 36 | 37 | ## Debug With Delve 38 | 39 | ### Prepare Code for Debug 40 | 41 | ```shell 42 | COMMIT_ID=c1c3d652 43 | mkdir -p /go/src/d7y.io/dragonfly 44 | git clone https://github.com/dragonflyoss/dragonfly.git /go/src/d7y.io/dragonfly/v2 45 | git reset --hard ${COMMIT_ID} 46 | ``` 47 | 48 | ### Debug Operations 49 | 50 | 1. Attach Process 51 | 52 | ```shell 53 | pid=$(pidof scheduler) # or dfget, manager 54 | dlv attach $pid 55 | ``` 56 | 57 | 2. Debug 58 | 59 | Follow 60 | -------------------------------------------------------------------------------- /build/images/dfdaemon/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=alpine:3.20 2 | 3 | FROM golang:1.23.8-alpine3.20 AS builder 4 | 5 | ARG GOPROXY 6 | ARG GOTAGS 7 | ARG GOGCFLAGS 8 | 9 | WORKDIR /go/src/d7y.io/dragonfly/v2 10 | 11 | RUN apk --no-cache add bash make gcc libc-dev git 12 | 13 | COPY . /go/src/d7y.io/dragonfly/v2 14 | 15 | RUN make build-dfget && make install-dfget 16 | 17 | FROM ${BASE_IMAGE} AS health 18 | 19 | ENV GRPC_HEALTH_PROBE_VERSION=v0.4.24 20 | 21 | RUN if [ "$(uname -m)" = "ppc64le" ]; then \ 22 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-ppc64le; \ 23 | elif [ "$(uname -m)" = "aarch64" ]; then \ 24 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-arm64; \ 25 | else \ 26 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64; \ 27 | fi && \ 28 | chmod +x /bin/grpc_health_probe 29 | 30 | FROM ${BASE_IMAGE} 31 | 32 | ENV PATH=/opt/dragonfly/bin:$PATH 33 | RUN echo "hosts: files dns" > /etc/nsswitch.conf 34 | 35 | COPY --from=builder /opt/dragonfly/bin/dfget /opt/dragonfly/bin/dfget 36 | COPY --from=health /bin/grpc_health_probe /bin/grpc_health_probe 37 | 38 | EXPOSE 65001 39 | 40 | ENTRYPOINT ["/opt/dragonfly/bin/dfget", "daemon"] 41 | -------------------------------------------------------------------------------- /build/images/scheduler/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=alpine:3.20 2 | 3 | FROM golang:1.23.8-alpine3.20 AS builder 4 | 5 | ARG GOPROXY 6 | ARG GOTAGS 7 | ARG GOGCFLAGS 8 | 9 | WORKDIR /go/src/d7y.io/dragonfly/v2 10 | 11 | RUN apk --no-cache add bash make gcc libc-dev git 12 | 13 | COPY . /go/src/d7y.io/dragonfly/v2 14 | 15 | RUN make build-scheduler && make install-scheduler 16 | 17 | FROM ${BASE_IMAGE} AS health 18 | 19 | ENV GRPC_HEALTH_PROBE_VERSION=v0.4.24 20 | 21 | RUN if [ "$(uname -m)" = "ppc64le" ]; then \ 22 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-ppc64le; \ 23 | elif [ "$(uname -m)" = "aarch64" ]; then \ 24 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-arm64; \ 25 | else \ 26 | wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64; \ 27 | fi && \ 28 | chmod +x /bin/grpc_health_probe 29 | 30 | FROM ${BASE_IMAGE} 31 | 32 | ENV PATH=/opt/dragonfly/bin:$PATH 33 | 34 | RUN echo "hosts: files dns" > /etc/nsswitch.conf 35 | 36 | RUN apk --no-cache add curl 37 | 38 | COPY --from=builder /opt/dragonfly/bin/scheduler /opt/dragonfly/bin/scheduler 39 | COPY --from=health /bin/grpc_health_probe /bin/grpc_health_probe 40 | 41 | EXPOSE 8002 42 | 43 | ENTRYPOINT ["/opt/dragonfly/bin/scheduler"] 44 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-delete.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache delete\f[R] \(em delete file from P2P cache system 6 | .SH SYNOPSIS 7 | Delete file from P2P cache system. 8 | .IP 9 | .EX 10 | dfcache delete <\-i cid> [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for delete 25 | .EE 26 | .SH SEE ALSO 27 | .IP \(bu 2 28 | dfcache \- the P2P cache client of dragonfly 29 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-doc.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache doc\f[R] \(em generate documents 6 | .SH SYNOPSIS 7 | Generate markdown documents for cmd: dfcache. 8 | .IP 9 | .EX 10 | dfcache doc [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for doc 25 | \-\-path string destination dir of generated markdown documents (default \(dq./\(dq) 26 | .EE 27 | .SH SEE ALSO 28 | .IP \(bu 2 29 | dfcache \- the P2P cache client of dragonfly 30 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-export.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache export\f[R] \(em export file from P2P cache system 6 | .SH SYNOPSIS 7 | Export file from P2P cache system. 8 | .IP 9 | .EX 10 | dfcache export <\-i cid> |<\-O output> [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for export 25 | \-l, \-\-local only export file from local cache 26 | \-O, \-\-output string export file path 27 | .EE 28 | .SH SEE ALSO 29 | .IP \(bu 2 30 | dfcache \- the P2P cache client of dragonfly 31 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-import.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache import\f[R] \(em import file into P2P cache system 6 | .SH SYNOPSIS 7 | Import file into P2P cache system. 8 | .IP 9 | .EX 10 | dfcache import <\-i cid> |<\-I file> [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for import 25 | \-I, \-\-input string import the given file into P2P network 26 | .EE 27 | .SH SEE ALSO 28 | .IP \(bu 2 29 | dfcache \- the P2P cache client of dragonfly 30 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-plugin.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache plugin\f[R] \(em show plugin 6 | .SH SYNOPSIS 7 | Show the plugin details of dragonfly. 8 | .IP 9 | .EX 10 | dfcache plugin [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for plugin 25 | .EE 26 | .SH SEE ALSO 27 | .IP \(bu 2 28 | dfcache \- the P2P cache client of dragonfly 29 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-stat.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache stat\f[R] \(em stat checks if a file exists in P2P cache 6 | system 7 | .SH SYNOPSIS 8 | Stat checks if a file exists in P2P cache system. 9 | .IP 10 | .EX 11 | dfcache stat <\-i cid> [flags] 12 | .EE 13 | .SS OPTIONS 14 | .IP 15 | .EX 16 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 17 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 18 | \-\-console whether logger output records to the stdout 19 | \-\-logdir string Dfcache log directory 20 | \-\-pprof\-port int listen port for pprof(default \-1) 21 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 22 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 23 | \-\-verbose whether logger use debug level 24 | \-\-workhome string Dfcache working directory 25 | \-h, \-\-help help for stat 26 | \-l, \-\-local only check task exists locally, and don\(aqt check other peers in P2P network 27 | .EE 28 | .SH SEE ALSO 29 | .IP \(bu 2 30 | dfcache \- the P2P cache client of dragonfly 31 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache-version.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfcache\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfcache version\f[R] \(em show version 6 | .SH SYNOPSIS 7 | Show the version details of dragonfly. 8 | .IP 9 | .EX 10 | dfcache version [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-i, \-\-cid string content or cache ID, e.g. sha256 digest of the content 16 | \-\-config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 17 | \-\-console whether logger output records to the stdout 18 | \-\-logdir string Dfcache log directory 19 | \-\-pprof\-port int listen port for pprof(default \-1) 20 | \-t, \-\-tag string different tags for the same cid will be recognized as different files in P2P network 21 | \-\-timeout duration Timeout for this cache operation, 0 is infinite 22 | \-\-verbose whether logger use debug level 23 | \-\-workhome string Dfcache working directory 24 | \-h, \-\-help help for version 25 | .EE 26 | .SH SEE ALSO 27 | .IP \(bu 2 28 | dfcache \- the P2P cache client of dragonfly 29 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_delete.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache delete** — delete file from P2P cache system 6 | 7 | # SYNOPSIS 8 | 9 | Delete file from P2P cache system. 10 | 11 | ```shell 12 | dfcache delete <-i cid> [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for delete 28 | ``` 29 | 30 | # SEE ALSO 31 | 32 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 33 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_doc.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache doc** — generate documents 6 | 7 | # SYNOPSIS 8 | 9 | Generate markdown documents for cmd: dfcache. 10 | 11 | ```shell 12 | dfcache doc [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ``` 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for doc 28 | --path string destination dir of generated markdown documents (default "./") 29 | ``` 30 | 31 | # SEE ALSO 32 | 33 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 34 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_export.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache export** — export file from P2P cache system 6 | 7 | # SYNOPSIS 8 | 9 | Export file from P2P cache system. 10 | 11 | ```shell 12 | dfcache export <-i cid> |<-O output> [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for export 28 | -l, --local only export file from local cache 29 | -O, --output string export file path 30 | ``` 31 | 32 | # SEE ALSO 33 | 34 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 35 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_import.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache import** — import file into P2P cache system 6 | 7 | # SYNOPSIS 8 | 9 | Import file into P2P cache system. 10 | 11 | ```shell 12 | dfcache import <-i cid> |<-I file> [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for import 28 | -I, --input string import the given file into P2P network 29 | ``` 30 | 31 | # SEE ALSO 32 | 33 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 34 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_plugin.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache plugin** — show plugin 6 | 7 | # SYNOPSIS 8 | 9 | Show the plugin details of dragonfly. 10 | 11 | ```shell 12 | dfcache plugin [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for plugin 28 | ``` 29 | 30 | # SEE ALSO 31 | 32 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 33 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_stat.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache stat** — stat checks if a file exists in P2P cache system 6 | 7 | # SYNOPSIS 8 | 9 | Stat checks if a file exists in P2P cache system. 10 | 11 | ```shell 12 | dfcache stat <-i cid> [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for stat 28 | -l, --local only check task exists locally, and don't check other peers in P2P network 29 | ``` 30 | 31 | # SEE ALSO 32 | 33 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 34 | -------------------------------------------------------------------------------- /build/package/docs/dfcache/dfcache_version.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfcache" Documentation 2 | 3 | # NAME 4 | 5 | **dfcache version** — show version 6 | 7 | # SYNOPSIS 8 | 9 | Show the version details of dragonfly. 10 | 11 | ```shell 12 | dfcache version [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -i, --cid string content or cache ID, e.g. sha256 digest of the content 19 | --config string the path of configuration file with yaml extension name, default is /etc/dragonfly/dfcache.yaml, it can also be set by env var: DFCACHE_CONFIG 20 | --console whether logger output records to the stdout 21 | --logdir string Dfcache log directory 22 | --pprof-port int listen port for pprof(default -1) 23 | -t, --tag string different tags for the same cid will be recognized as different files in P2P network 24 | --timeout duration Timeout for this cache operation, 0 is infinite 25 | --verbose whether logger use debug level 26 | --workhome string Dfcache working directory 27 | -h, --help help for version 28 | ``` 29 | 30 | # SEE ALSO 31 | 32 | - [dfcache](dfcache.md) - the P2P cache client of dragonfly 33 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore-copy.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfstore\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfstore cp\f[R] \(em copies a local file or dragonfly object to 6 | another location locally or in dragonfly object storage 7 | .SH SYNOPSIS 8 | Copies a local file or dragonfly object to another location locally or 9 | in dragonfly object storage. 10 | .IP 11 | .EX 12 | dfstore cp [flags] 13 | .EE 14 | .SS OPTIONS 15 | .IP 16 | .EX 17 | \-\-filter string filter is used to generate a unique task id by filtering unnecessary query params in the URL, it is separated by & character 18 | \-h, \-\-help help for cp 19 | \-\-max\-replicas int maxReplicas is the maximum number of replicas of an object cache in seed peers (default 3) 20 | \-m, \-\-mode int mode is the mode in which the backend is written, when the value is 0, it represents AsyncWriteBack, and when the value is 1, it represents WriteBack 21 | \-e, \-\-endpoint string endpoint of object storage service (default \(dqhttp://127.0.0.1:65004\(dq) 22 | .EE 23 | .SH SEE ALSO 24 | .IP \(bu 2 25 | dfstore \- object storage client of dragonfly 26 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore-remove.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfstore\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfstore rm\f[R] \(em remove object from P2P storage system 6 | .SH SYNOPSIS 7 | Remove object from P2P storage system. 8 | .IP 9 | .EX 10 | dfstore rm [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-h, \-\-help help for rm 16 | \-e, \-\-endpoint string endpoint of object storage service (default \(dqhttp://127.0.0.1:65004\(dq) 17 | .EE 18 | .SH SEE ALSO 19 | .IP \(bu 2 20 | dfstore \- object storage client of dragonfly 21 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore-version.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfstore\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfstore version\f[R] \(em show version 6 | .SH SYNOPSIS 7 | Show the version details of dragonfly. 8 | .IP 9 | .EX 10 | dfstore version [flags] 11 | .EE 12 | .SS OPTIONS 13 | .IP 14 | .EX 15 | \-h, \-\-help help for rm 16 | .EE 17 | .SH SEE ALSO 18 | .IP \(bu 2 19 | dfstore \- object storage client of dragonfly 20 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore.1: -------------------------------------------------------------------------------- 1 | .\" Automatically generated by Pandoc 3.7.0.1 2 | .\" 3 | .TH "DFCACHE" "1" "" "Version v2.2.0" "Frivolous \(lqDfstore\(rq Documentation" 4 | .SH NAME 5 | \f[B]dfstore\f[R] \(em object storage client of dragonfly 6 | .SH SYNOPSIS 7 | Dfstore is a storage client for dragonfly. 8 | It can rely on different types of object storage, such as S3 or OSS, to 9 | provide stable object storage capabilities dfstore uses the entire P2P 10 | network as a cache when storing objects. 11 | Rely on S3 or OSS as the backend to ensure storage reliability. 12 | In the process of object storage, P2P Cache is effectively used for fast 13 | read and write storage. 14 | .SS OPTIONS 15 | .IP 16 | .EX 17 | \-h, \-\-help help for rm 18 | .EE 19 | .SH SEE ALSO 20 | .IP \(bu 2 21 | dfstore copy \- copies a local file or dragonfly object to another 22 | location locally or in dragonfly object storage 23 | .IP \(bu 2 24 | dfcache remove \- remove object from P2P storage system 25 | .IP \(bu 2 26 | dfcache version \- show version 27 | .SH BUGS 28 | See GitHub Issues: \c 29 | .UR https://github.com/dragonflyoss/dragonfly/issues 30 | .UE \c 31 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfstore" Documentation 2 | 3 | # NAME 4 | 5 | **dfstore** — object storage client of dragonfly 6 | 7 | # SYNOPSIS 8 | 9 | Dfstore is a storage client for dragonfly. It can rely on different types of object storage, 10 | such as S3 or OSS, to provide stable object storage capabilities 11 | dfstore uses the entire P2P network as a cache when storing objects. 12 | Rely on S3 or OSS as the backend to ensure storage reliability. 13 | In the process of object storage, P2P Cache is effectively used for fast read and write storage. 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -h, --help help for rm 19 | ``` 20 | 21 | # SEE ALSO 22 | 23 | - [dfstore copy](dfstore_copy.md) - copies a local file or dragonfly object to another location locally or in dragonfly object storage 24 | - [dfcache remove](dfstore_remove.md) - remove object from P2P storage system 25 | - [dfcache version](dfstore_version.md) - show version 26 | 27 | # BUGS 28 | 29 | See GitHub Issues: 30 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore_copy.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfstore" Documentation 2 | 3 | # NAME 4 | 5 | **dfstore cp** — copies a local file or dragonfly object to another location locally or in dragonfly object storage 6 | 7 | # SYNOPSIS 8 | 9 | Copies a local file or dragonfly object to another location locally or in dragonfly object storage. 10 | 11 | ```shell 12 | dfstore cp [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | --filter string filter is used to generate a unique task id by filtering unnecessary query params in the URL, it is separated by & character 19 | -h, --help help for cp 20 | --max-replicas int maxReplicas is the maximum number of replicas of an object cache in seed peers (default 3) 21 | -m, --mode int mode is the mode in which the backend is written, when the value is 0, it represents AsyncWriteBack, and when the value is 1, it represents WriteBack 22 | -e, --endpoint string endpoint of object storage service (default "http://127.0.0.1:65004") 23 | ``` 24 | 25 | # SEE ALSO 26 | 27 | - [dfstore](dfstore.md) - object storage client of dragonfly 28 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore_remove.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfstore" Documentation 2 | 3 | # NAME 4 | 5 | **dfstore rm** — remove object from P2P storage system 6 | 7 | # SYNOPSIS 8 | 9 | Remove object from P2P storage system. 10 | 11 | ```shell 12 | dfstore rm [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -h, --help help for rm 19 | -e, --endpoint string endpoint of object storage service (default "http://127.0.0.1:65004") 20 | ``` 21 | 22 | # SEE ALSO 23 | 24 | - [dfstore](dfstore.md) - object storage client of dragonfly 25 | -------------------------------------------------------------------------------- /build/package/docs/dfstore/dfstore_version.md: -------------------------------------------------------------------------------- 1 | % DFCACHE(1) Version v2.2.0 | Frivolous "Dfstore" Documentation 2 | 3 | # NAME 4 | 5 | **dfstore version** — show version 6 | 7 | # SYNOPSIS 8 | 9 | Show the version details of dragonfly. 10 | 11 | ```shell 12 | dfstore version [flags] 13 | ``` 14 | 15 | ## OPTIONS 16 | 17 | ```shell 18 | -h, --help help for rm 19 | ``` 20 | 21 | # SEE ALSO 22 | 23 | - [dfstore](dfstore.md) - object storage client of dragonfly 24 | -------------------------------------------------------------------------------- /build/package/nfpm/dfcache.yaml: -------------------------------------------------------------------------------- 1 | name: dfcache 2 | arch: amd64 3 | platform: linux 4 | epoch: 2 5 | version: v${SEMVER} 6 | version_schema: semver 7 | release: ${VERSION_RELEASE} 8 | section: default 9 | priority: extra 10 | description: dfcache is the cache client to of dragonfly that communicates with dfdaemon and operates on files in P2P network 11 | license: "Apache 2.0" 12 | homepage: https://d7y.io 13 | maintainer: Dragonfly Maintainers 14 | 15 | provides: 16 | - dfcache 17 | 18 | contents: 19 | - src: /root/bin/linux_amd64/dfcache 20 | dst: /usr/bin/dfcache 21 | 22 | - src: /root/docs/dfcache/dfcache.1 23 | dst: /usr/share/man/man1/dfcache.1 24 | 25 | - src: /root/docs/dfcache/dfcache-delete.1 26 | dst: /usr/share/man/man1/dfcache-delete.1 27 | 28 | - src: /root/docs/dfcache/dfcache-doc.1 29 | dst: /usr/share/man/man1/dfcache-doc.1 30 | 31 | - src: /root/docs/dfcache/dfcache-export.1 32 | dst: /usr/share/man/man1/dfcache-export.1 33 | 34 | - src: /root/docs/dfcache/dfcache-import.1 35 | dst: /usr/share/man/man1/dfcache-import.1 36 | 37 | - src: /root/docs/dfcache/dfcache-plugin.1 38 | dst: /usr/share/man/man1/dfcache-plugin.1 39 | 40 | - src: /root/docs/dfcache/dfcache-stat.1 41 | dst: /usr/share/man/man1/dfcache-stat.1 42 | 43 | - src: /root/docs/dfcache/dfcache-version.1 44 | dst: /usr/share/man/man1/dfcache-version.1 45 | 46 | - src: /root/License 47 | dst: /usr/share/doc/dfcache/License 48 | 49 | - src: /root/CHANGELOG.md 50 | dst: /usr/share/doc/dfcache/ChangeLog 51 | -------------------------------------------------------------------------------- /build/package/nfpm/dfget-postinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$D7Y_DEBUG" == "true" ]]; then 4 | set -x 5 | echo post install with param: "$@" 6 | fi 7 | 8 | chmod a+s /usr/bin/dfget 9 | 10 | if [[ -f /bin/systemctl || -f /usr/bin/systemctl ]]; then 11 | systemctl daemon-reload; systemctl enable --now dfget-daemon.service 12 | fi 13 | -------------------------------------------------------------------------------- /build/package/nfpm/dfget-postremove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$D7Y_DEBUG" == "true" ]]; then 4 | set -x 5 | echo post remove with param: "$@" 6 | fi 7 | 8 | if [[ -f /bin/systemctl || -f /usr/bin/systemctl ]]; then 9 | systemctl daemon-reload 10 | fi 11 | -------------------------------------------------------------------------------- /build/package/nfpm/dfget-preinstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$D7Y_DEBUG" == "true" ]]; then 4 | set -x 5 | echo pre install with param: "$@" 6 | fi 7 | 8 | # stop dfget daemon before upgrading 9 | if [[ -f "/etc/systemd/system/dfget-daemon.service" ]]; then 10 | if [[ -f /bin/systemctl || -f /usr/bin/systemctl ]]; then 11 | systemctl stop dfget-daemon.service 12 | fi 13 | fi 14 | -------------------------------------------------------------------------------- /build/package/nfpm/dfget-preremove.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$D7Y_DEBUG" == "true" ]]; then 4 | set -x 5 | echo pre remove with param: "$@" 6 | fi 7 | 8 | upgrade=0 9 | 10 | # in rpm install: 11 | # refer: https://docs.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s04s05.html 12 | if [[ "$1" -gt 0 ]]; then 13 | upgrade=1 14 | fi 15 | 16 | # in deb install 17 | # refer: https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html 18 | if [[ "$1" =~ "upgrade" ]]; then 19 | upgrade=1 20 | fi 21 | 22 | # not in upgrade, purge systemd service 23 | if [[ "$upgrade" -eq 0 ]]; then 24 | if [[ -f /bin/systemctl || -f /usr/bin/systemctl ]]; then 25 | systemctl stop dfget-daemon.service; systemctl disable dfget-daemon.service 26 | fi 27 | fi 28 | -------------------------------------------------------------------------------- /build/package/nfpm/dfstore.yaml: -------------------------------------------------------------------------------- 1 | name: dfstore 2 | arch: amd64 3 | platform: linux 4 | epoch: 2 5 | version: v${SEMVER} 6 | version_schema: semver 7 | release: ${VERSION_RELEASE} 8 | section: default 9 | priority: extra 10 | description: dfstore is a storage client for dragonfly. It can rely on different types of object storage, such as S3 or OSS, to provide stable object storage capabilities. 11 | license: "Apache 2.0" 12 | homepage: https://d7y.io 13 | maintainer: Dragonfly Maintainers 14 | 15 | provides: 16 | - dfstore 17 | 18 | contents: 19 | - src: /root/bin/linux_amd64/dfstore 20 | dst: /usr/bin/dfstore 21 | 22 | - src: /root/docs/dfstore/dfstore.1 23 | dst: /usr/share/man/man1/dfstore.1 24 | 25 | - src: /root/docs/dfstore/dfstore-copy.1 26 | dst: /usr/share/man/man1/dfstore-copy.1 27 | 28 | - src: /root/docs/dfstore/dfstore-remove.1 29 | dst: /usr/share/man/man1/dfstore-remove.1 30 | 31 | - src: /root/docs/dfstore/dfstore-version.1 32 | dst: /usr/share/man/man1/dfstore-version.1 33 | 34 | - src: /root/License 35 | dst: /usr/share/doc/dfstore/License 36 | 37 | - src: /root/CHANGELOG.md 38 | dst: /usr/share/doc/dfstore/ChangeLog 39 | -------------------------------------------------------------------------------- /build/package/nfpm/systemd/dfget-daemon.service.d/CPUQuota.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | CPUQuota=100% 3 | -------------------------------------------------------------------------------- /build/package/nfpm/systemd/dfget-daemon.service.d/CPUShares.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | CPUShares=400 3 | -------------------------------------------------------------------------------- /build/package/nfpm/systemd/dfget-daemon.service.d/MemoryLimit.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | MemoryLimit=2147483648 3 | -------------------------------------------------------------------------------- /build/package/nfpm/systemd/fix.dfget-daemon.cpuset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # skip unsupported and newly kernel 4 | if [ ! -d /sys/fs/cgroup/cpuset,cpu,cpuacct ]; then 5 | exit 0 6 | fi 7 | 8 | # fix cpu set not settled in old kernel 9 | mkdir -p /sys/fs/cgroup/cpuset,cpu,cpuacct/dragonfly.slice/dfget-daemon.service 10 | cat /sys/fs/cgroup/cpuset,cpu,cpuacct/cpuset.cpus > \ 11 | /sys/fs/cgroup/cpuset,cpu,cpuacct/dragonfly.slice/cpuset.cpus 12 | cat /sys/fs/cgroup/cpuset,cpu,cpuacct/cpuset.mems > \ 13 | /sys/fs/cgroup/cpuset,cpu,cpuacct/dragonfly.slice/cpuset.mems 14 | cat /sys/fs/cgroup/cpuset,cpu,cpuacct/cpuset.cpus > \ 15 | /sys/fs/cgroup/cpuset,cpu,cpuacct/dragonfly.slice/dfget-daemon.service/cpuset.cpus 16 | cat /sys/fs/cgroup/cpuset,cpu,cpuacct/cpuset.mems > \ 17 | /sys/fs/cgroup/cpuset,cpu,cpuacct/dragonfly.slice/dfget-daemon.service/cpuset.mems 18 | -------------------------------------------------------------------------------- /build/plugin-builder/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.23.8-alpine3.20 2 | 3 | ARG GOPROXY 4 | ARG GOTAGS 5 | ARG GOGCFLAGS 6 | 7 | WORKDIR /go/src/d7y.io/dragonfly/v2 8 | 9 | RUN apk --no-cache add bash make gcc libc-dev git 10 | 11 | COPY . /go/src/d7y.io/dragonfly/v2 12 | 13 | ENV CGO_ENABLED="1" 14 | ENV GO111MODULE="on" 15 | 16 | COPY build/plugin-builder/build.sh / 17 | -------------------------------------------------------------------------------- /build/plugin-builder/images/dfdaemon/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=alpine:3.17 2 | 3 | FROM ${BASE_IMAGE} 4 | 5 | ENV PATH=/opt/dragonfly/bin:$PATH 6 | RUN echo "hosts: files dns" > /etc/nsswitch.conf && \ 7 | mkdir -p /usr/local/dragonfly/plugins/ 8 | 9 | COPY ./artifacts/binaries/dfget /opt/dragonfly/bin/dfget 10 | COPY ./artifacts/plugins/d7y-resource-plugin-* /usr/local/dragonfly/plugins/ 11 | 12 | EXPOSE 65001 13 | 14 | ENTRYPOINT ["/opt/dragonfly/bin/dfget", "daemon"] 15 | 16 | -------------------------------------------------------------------------------- /build/plugin-builder/images/manager/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=alpine:3.17 2 | 3 | FROM ${BASE_IMAGE} 4 | 5 | WORKDIR /opt/dragonfly 6 | 7 | ENV PATH=/opt/dragonfly/bin:$PATH 8 | 9 | RUN echo "hosts: files dns" > /etc/nsswitch.conf && \ 10 | mkdir -p /usr/local/dragonfly/plugins/ 11 | 12 | COPY ./artifacts/binaries/manager /opt/dragonfly/bin/server 13 | COPY ./artifacts/plugins/d7y-manager-plugin-* /usr/local/dragonfly/plugins/ 14 | 15 | EXPOSE 8080 65003 16 | 17 | ENTRYPOINT ["/opt/dragonfly/bin/server"] 18 | -------------------------------------------------------------------------------- /build/plugin-builder/images/scheduler/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE=alpine:3.17 2 | 3 | FROM ${BASE_IMAGE} 4 | 5 | ENV PATH=/opt/dragonfly/bin:$PATH 6 | RUN echo "hosts: files dns" > /etc/nsswitch.conf && \ 7 | mkdir -p /usr/local/dragonfly/plugins/ 8 | 9 | COPY ./artifacts/binaries/scheduler /opt/dragonfly/bin/scheduler 10 | COPY ./artifacts/plugins/d7y-scheduler-plugin-* /usr/local/dragonfly/plugins/ 11 | 12 | EXPOSE 8002 13 | 14 | ENTRYPOINT ["/opt/dragonfly/bin/scheduler"] 15 | -------------------------------------------------------------------------------- /client/config/dfget_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | 3 | /* 4 | * Copyright 2020 The Dragonfly Authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package config 20 | 21 | import ( 22 | "golang.org/x/time/rate" 23 | 24 | "d7y.io/dragonfly/v2/client/util" 25 | "d7y.io/dragonfly/v2/pkg/unit" 26 | ) 27 | 28 | var dfgetConfig = ClientOption{ 29 | URL: "", 30 | Output: "", 31 | Timeout: 0, 32 | BenchmarkRate: 128 * unit.KB, 33 | RateLimit: util.RateLimit{ 34 | Limit: rate.Limit(DefaultTotalDownloadLimit), 35 | }, 36 | Md5: "", 37 | DigestMethod: "", 38 | DigestValue: "", 39 | Tag: "", 40 | Application: "", 41 | Priority: 0, 42 | Cacerts: nil, 43 | Filter: "", 44 | Header: nil, 45 | DisableBackSource: false, 46 | Insecure: false, 47 | ShowProgress: false, 48 | Recursive: false, 49 | RecursiveLevel: 5, 50 | } 51 | -------------------------------------------------------------------------------- /client/config/dfget_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | 3 | /* 4 | * Copyright 2020 The Dragonfly Authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package config 20 | 21 | import ( 22 | "golang.org/x/time/rate" 23 | 24 | "d7y.io/dragonfly/v2/client/util" 25 | ) 26 | 27 | var dfgetConfig = ClientOption{ 28 | URL: "", 29 | Output: "", 30 | Timeout: 0, 31 | RateLimit: util.RateLimit{ 32 | Limit: rate.Limit(DefaultTotalDownloadLimit), 33 | }, 34 | Md5: "", 35 | DigestMethod: "", 36 | DigestValue: "", 37 | Tag: "", 38 | Application: "", 39 | Priority: 0, 40 | Cacerts: nil, 41 | Filter: "", 42 | Header: nil, 43 | DisableBackSource: false, 44 | Insecure: false, 45 | ShowProgress: false, 46 | Recursive: false, 47 | RecursiveLevel: 5, 48 | LogMaxSize: DefaultLogRotateMaxSize, 49 | LogMaxAge: DefaultLogRotateMaxAge, 50 | LogMaxBackups: DefaultLogRotateMaxBackups, 51 | } 52 | -------------------------------------------------------------------------------- /client/config/fixme.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import ( 20 | "crypto/tls" 21 | "net" 22 | 23 | "github.com/johanbrandhorst/certify" 24 | 25 | logger "d7y.io/dragonfly/v2/internal/dflog" 26 | ) 27 | 28 | func GetCertificate(certifyClient *certify.Certify) func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { 29 | return func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { 30 | // FIXME peers need pure ip cert, certify checks the ServerName, so workaround here 31 | if hello.ServerName == "" { 32 | host, _, err := net.SplitHostPort(hello.Conn.LocalAddr().String()) 33 | if err == nil { 34 | hello.ServerName = host 35 | } else { 36 | logger.Warnf("failed to get host from %s: %s", hello.Conn.LocalAddr().String(), err) 37 | } 38 | } 39 | return certifyClient.GetCertificate(hello) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /client/config/testdata/certs/ca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDYzCCAkugAwIBAgIJALbS07JnDcXbMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV 3 | BAYTAkNOMQwwCgYDVQQIDANkN3kxDDAKBgNVBAcMA2Q3eTEMMAoGA1UECgwDZDd5 4 | MQwwCgYDVQQLDANkN3kxDDAKBgNVBAMMA2Q3eTESMBAGCSqGSIb3DQEJARYDZDd5 5 | MCAXDTIxMDMwMjA1NTczOVoYDzIxMjEwMjA2MDU1NzM5WjBnMQswCQYDVQQGEwJD 6 | TjEMMAoGA1UECAwDZDd5MQwwCgYDVQQHDANkN3kxDDAKBgNVBAoMA2Q3eTEMMAoG 7 | A1UECwwDZDd5MQwwCgYDVQQDDANkN3kxEjAQBgkqhkiG9w0BCQEWA2Q3eTCCASIw 8 | DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMLdNZPju31aKEHddiamv7zO/jME 9 | vtp9VK5FRHMWpqWCSIRbP8roMhMIeWGI68uRWMztrIbTiaY2NkI3fEA4J3Aql4O7 10 | 9x2cqQqILnKgJ7+Wx6yGv8khdfRkVAIyloi0NL29b5SpKqkXJbliXolo+993MPRd 11 | ZXLU4SK8nTh66yG3mSQz7zCC5Esbz574afTHuFG8UBQa7VFbwho6dHrsPDhzl43e 12 | hQuKPh1Zj0kvJ4U3aGZr0OmOk4t0W9XGiaeJoFmzwoPH702sL0t4cwDPy0yGi+g0 13 | 3EMOrc56uF4V0LdzOZsQX4IdUDNeoNKgRrr+4lVM3orCYwwUTwGTFMgS2tMCAwEA 14 | AaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAqKzxZmdX1WCC 15 | /p+oSIrNjRNeFDhXg7UPqbQcD/mk2rRel0sT2DbMiMtMTi3Yzdu6KI7ddmrdaxOZ 16 | ZM13FUdejThxrET3RAFmxVn3FftexczyHBYdcHnE0WrxNfjI3nSYt51u/h6kw7KT 17 | ePfGw2Xou+H3HTGOZoK4s0NRo3KxJBJW1zJjec2tN/XbdKOiP2QuWR8Uqk9GVGO4 18 | tJYVbXwOnvmBD+Ga/+JBFPVSX4ghZ3zX75ORH7DUBE66eiHoY9uW0cr0Vsx6nV/e 19 | TkV3x0EUgfGTni69zOi47Mok6pgTQ37yxysjpG8EQhRtUhfiyOnb4oysSz8K8GTE 20 | g6oF84YpeQ== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /client/config/testdata/certs/sca.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDTDCCAjQCCQCG2VXiUpgjrTANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJD 3 | TjEMMAoGA1UECAwDZDd5MQwwCgYDVQQHDANkN3kxDDAKBgNVBAoMA2Q3eTEMMAoG 4 | A1UECwwDZDd5MQwwCgYDVQQDDANkN3kxEjAQBgkqhkiG9w0BCQEWA2Q3eTAgFw0y 5 | MTAzMDIwNTU4MjRaGA8yMTIxMDIwNjA1NTgyNFowZzELMAkGA1UEBhMCQ04xDDAK 6 | BgNVBAgMA2Q3eTEMMAoGA1UEBwwDZDd5MQwwCgYDVQQKDANkN3kxDDAKBgNVBAsM 7 | A2Q3eTEMMAoGA1UEAwwDZDd5MRIwEAYJKoZIhvcNAQkBFgNkN3kwggEiMA0GCSqG 8 | SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY6bmTukfYkD2Z4GegErmq9K/CFAKybNua 9 | OPNTXj4R0lbqxjGFqQ9tIqJA7I+Ha/ptNwU/kHOTETVguJKSAPU5fkJsa5pMA8LP 10 | 2JiI7HzyQSotNomauye3n/bL+qwxD9d+D5ZlaA6QNB9ok6IzQ1gCI7ip794sc4tz 11 | 0SKGMyxYY5LHW8jppEc2mtItGJkzzrTob7pdOVEgPlwFrJ8tAL/K4hQ7ChQRsOHL 12 | ZXYdlQeCOMol5yBmAz4AFBupFI2XwNbrEwSFHkKi+ug5xCe0eiOm1cTL5vv5HA7O 13 | d0AAUZtIT7Mco8TE7m4IeArPLSFWfLp4JyIKOGYpIfivMT2H97kJAgMBAAEwDQYJ 14 | KoZIhvcNAQEFBQADggEBAGHFpWr+VGUglAAzdGoRYS8yqmpwxOYXH5rTSTZGBST/ 15 | 1IT03nISI6vEUk90GmFilmD1/TVp4KzmpD3dndlQx3r52Zg1XPN2KKG87g5UdhCs 16 | A5l000dtHekhk+DO2tjQgEKg5+EYMYoki5mEkSbyHkMMY8D6w5A130fpw10ZeN1z 17 | B/v/1PiVkZfu1kbnTZICQDsb4xI/2Sw2x0qKXp1oYzIDt8fZATNJgWhzv47xLLXF 18 | XQM7Yj0HQ3txAi6qOMDw1sYf/TEc1k4VC9J//QJb5/kNnWcAheLPCm3D1+CnAxcD 19 | vL928p4GmUIGbzxm3/WbWfLosSwxq5y4P5bbEd3niM4= 20 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /client/config/testdata/config/proxy.yaml: -------------------------------------------------------------------------------- 1 | registryMirror: 2 | # url for the registry mirror 3 | url: https://index.docker.io 4 | # whether to ignore https certificate errors 5 | insecure: false 6 | # optional certificates if the remote server uses self-signed certificates 7 | certs: [] 8 | # whether to request the remote registry directly 9 | direct: false 10 | 11 | proxies: 12 | # proxy all http image layer download requests with dfget 13 | - regx: blobs/sha256.* 14 | # change http requests to some-registry to https and proxy them with dfget 15 | - regx: some-registry/ 16 | useHTTPS: true 17 | # proxy requests directly, without dfget 18 | - regx: no-proxy-reg 19 | direct: true 20 | # proxy requests with redirect 21 | - regx: some-registry 22 | redirect: another-registry 23 | 24 | hijackHTTPS: 25 | # key pair used to hijack https requests 26 | cert: ./testdata/certs/sca.crt 27 | key: ./testdata/certs/sca.key 28 | hosts: 29 | - regx: mirror.aliyuncs.com:443 # regexp to match request hosts 30 | # whether to ignore https certificate errors 31 | insecure: false 32 | # optional certificates if the host uses self-signed certificates 33 | certs: [] 34 | -------------------------------------------------------------------------------- /client/daemon/daemon_stub.go: -------------------------------------------------------------------------------- 1 | //go:build !linux 2 | 3 | /* 4 | * Copyright 2020 The Dragonfly Authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package daemon 20 | 21 | func switchNetNamespace(target string) (func() error, error) { 22 | return func() error { 23 | return nil 24 | }, nil 25 | } 26 | -------------------------------------------------------------------------------- /client/daemon/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package metrics 18 | 19 | import ( 20 | "testing" 21 | ) 22 | 23 | func TestNew(t *testing.T) { 24 | addr := "localhost:8080" 25 | server := New(addr) 26 | 27 | if server.Addr != addr { 28 | t.Errorf("Expected server address to be %s, but got %s", addr, server.Addr) 29 | } 30 | 31 | if server.Handler == nil { 32 | t.Error("Expected server handler to not be nil") 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /client/daemon/peer/peerid_generator.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package peer 18 | 19 | import "d7y.io/dragonfly/v2/pkg/idgen" 20 | 21 | const ( 22 | defaultPeerIDBufferSize = 1024 23 | ) 24 | 25 | type IDGenerator interface { 26 | PeerID() string 27 | } 28 | 29 | type peerIDGenerator struct { 30 | ip string 31 | ch chan string 32 | } 33 | 34 | func NewPeerIDGenerator(ip string) IDGenerator { 35 | p := &peerIDGenerator{ 36 | ip: ip, 37 | ch: make(chan string, defaultPeerIDBufferSize), 38 | } 39 | go p.run() 40 | return p 41 | } 42 | 43 | func (p *peerIDGenerator) PeerID() string { 44 | return <-p.ch 45 | } 46 | 47 | func (p *peerIDGenerator) run() { 48 | for { 49 | p.ch <- idgen.PeerIDV1(p.ip) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /client/daemon/peer/peertask_bitmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package peer 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/bits-and-blooms/bitset" 23 | ) 24 | 25 | type Bitmap struct { 26 | bits *bitset.BitSet 27 | mu sync.RWMutex 28 | } 29 | 30 | func NewBitmap() *Bitmap { 31 | return &Bitmap{ 32 | bits: bitset.New(8), 33 | } 34 | } 35 | 36 | func NewBitmapWithCap(c int32) *Bitmap { 37 | return &Bitmap{ 38 | bits: bitset.New(uint(c)), 39 | } 40 | } 41 | 42 | func (b *Bitmap) IsSet(i int32) bool { 43 | b.mu.RLock() 44 | defer b.mu.RUnlock() 45 | return b.bits.Test(uint(i)) 46 | } 47 | 48 | func (b *Bitmap) Set(i int32) { 49 | b.mu.Lock() 50 | defer b.mu.Unlock() 51 | b.bits.Set(uint(i)) 52 | } 53 | 54 | func (b *Bitmap) Clean(i int32) { 55 | b.mu.Lock() 56 | defer b.mu.Unlock() 57 | b.bits.Clear(uint(i)) 58 | } 59 | 60 | func (b *Bitmap) Settled() int32 { 61 | b.mu.RLock() 62 | defer b.mu.RUnlock() 63 | return int32(b.bits.Count()) 64 | } 65 | 66 | func (b *Bitmap) Sets(xs ...int32) { 67 | for _, x := range xs { 68 | b.Set(x) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /client/daemon/peer/peertask_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package peer 18 | 19 | import "testing" 20 | 21 | func TestBitmap_Sets(t *testing.T) { 22 | b := NewBitmap() 23 | for i := int32(0); i < 512; i++ { 24 | b.Set(i) 25 | } 26 | b.Sets(2, 3, 3, 4) 27 | //t.Logf("%s, %d", b.String(), b.Settled()) 28 | } 29 | -------------------------------------------------------------------------------- /client/daemon/pex/delegate.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package pex 18 | 19 | import "encoding/json" 20 | 21 | type peerExchangeDelegate struct { 22 | meta *MemberMeta 23 | } 24 | 25 | type MemberMeta struct { 26 | // keep private field, so isLocal meta in other members' list is false 27 | isLocal bool 28 | HostID string 29 | IP string 30 | RPCPort int32 31 | ProxyPort int32 32 | } 33 | 34 | func newPeerExchangeDelegate(nodeMata *MemberMeta) *peerExchangeDelegate { 35 | return &peerExchangeDelegate{meta: nodeMata} 36 | } 37 | 38 | func (p *peerExchangeDelegate) NodeMeta(limit int) []byte { 39 | data, _ := json.Marshal(p.meta) 40 | return data 41 | } 42 | 43 | func (p *peerExchangeDelegate) NotifyMsg(bytes []byte) { 44 | return 45 | } 46 | 47 | func (p *peerExchangeDelegate) GetBroadcasts(overhead, limit int) [][]byte { 48 | return nil 49 | } 50 | 51 | func (p *peerExchangeDelegate) LocalState(join bool) []byte { 52 | return nil 53 | } 54 | 55 | func (p *peerExchangeDelegate) MergeRemoteState(buf []byte, join bool) { 56 | return 57 | } 58 | -------------------------------------------------------------------------------- /client/daemon/proxy/proxy_writter.go: -------------------------------------------------------------------------------- 1 | package proxy 2 | 3 | import ( 4 | "io" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | // copy from golang library, see https://github.com/golang/go/blob/master/src/net/http/httputil/reverseproxy.go 10 | type maxLatencyWriter struct { 11 | dst io.Writer 12 | flush func() error 13 | latency time.Duration // non-zero; negative means to flush immediately 14 | 15 | mu sync.Mutex // protects t, flushPending, and dst.Flush 16 | t *time.Timer 17 | flushPending bool 18 | } 19 | 20 | func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { 21 | m.mu.Lock() 22 | defer m.mu.Unlock() 23 | n, err = m.dst.Write(p) 24 | if m.latency < 0 { 25 | m.flush() // nolint: errcheck 26 | return 27 | } 28 | if m.flushPending { 29 | return 30 | } 31 | if m.t == nil { 32 | m.t = time.AfterFunc(m.latency, m.delayedFlush) 33 | } else { 34 | m.t.Reset(m.latency) 35 | } 36 | m.flushPending = true 37 | return 38 | } 39 | 40 | func (m *maxLatencyWriter) delayedFlush() { 41 | m.mu.Lock() 42 | defer m.mu.Unlock() 43 | if !m.flushPending { // if stop was called but AfterFunc already started this goroutine 44 | return 45 | } 46 | m.flush() // nolint: errcheck 47 | m.flushPending = false 48 | } 49 | 50 | func (m *maxLatencyWriter) stop() { 51 | m.mu.Lock() 52 | defer m.mu.Unlock() 53 | m.flushPending = false 54 | if m.t != nil { 55 | m.t.Stop() 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /client/daemon/rpcserver/peer_exchange.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package rpcserver 18 | 19 | import ( 20 | "google.golang.org/grpc/codes" 21 | "google.golang.org/grpc/status" 22 | 23 | dfdaemonv1 "d7y.io/api/v2/pkg/apis/dfdaemon/v1" 24 | ) 25 | 26 | func (s *server) PeerExchange(exchangeServer dfdaemonv1.Daemon_PeerExchangeServer) error { 27 | if s.peerExchanger == nil { 28 | return status.New(codes.Unavailable, "peer exchange is disabled").Err() 29 | } 30 | return s.peerExchanger.PeerExchange(exchangeServer) 31 | } 32 | -------------------------------------------------------------------------------- /client/daemon/storage/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package storage 18 | 19 | import ( 20 | "errors" 21 | "os" 22 | ) 23 | 24 | const ( 25 | taskData = "data" 26 | taskMetadata = "metadata" 27 | 28 | defaultFileMode = os.FileMode(0644) 29 | defaultDirectoryMode = os.FileMode(0700) // used unless overridden in config 30 | ) 31 | 32 | var ( 33 | ErrShortRead = errors.New("short read") 34 | ) 35 | -------------------------------------------------------------------------------- /client/daemon/test/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package test 18 | 19 | const ( 20 | DataDir = "../test/testdata" 21 | File = DataDir + "/go.html" 22 | ) 23 | -------------------------------------------------------------------------------- /client/daemon/upload/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package upload 18 | 19 | type DownloadParams struct { 20 | TaskPrefix string `uri:"task_prefix" binding:"required"` 21 | TaskID string `uri:"task_id" binding:"required"` 22 | } 23 | 24 | type DownloadQuery struct { 25 | PeerID string `form:"peerId" binding:"required"` 26 | } 27 | -------------------------------------------------------------------------------- /client/util/keepalive.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //go:generate mockgen -destination mocks/keepalive_mock.go -source keepalive.go -package mocks 18 | 19 | package util 20 | 21 | import ( 22 | "time" 23 | 24 | "go.uber.org/atomic" 25 | 26 | logger "d7y.io/dragonfly/v2/internal/dflog" 27 | ) 28 | 29 | type KeepAlive interface { 30 | Keep() 31 | Alive(alive time.Duration) bool 32 | } 33 | 34 | type keepAlive struct { 35 | name string 36 | access atomic.Int64 37 | } 38 | 39 | func NewKeepAlive(name string) KeepAlive { 40 | return &keepAlive{ 41 | name: name, 42 | } 43 | } 44 | 45 | func (k *keepAlive) Keep() { 46 | k.access.Store(time.Now().UnixNano()) 47 | } 48 | 49 | func (k *keepAlive) Alive(alive time.Duration) bool { 50 | var ( 51 | now = time.Now() 52 | access = time.Unix(0, k.access.Load()) 53 | ) 54 | 55 | logger.Debugf("%s keepalive check, last access: %s, alive time: %f seconds, current time: %s", 56 | k.name, access.Format(time.RFC3339), alive.Seconds(), now) 57 | return access.Add(alive).After(now) 58 | } 59 | -------------------------------------------------------------------------------- /cmd/dependency/base/option.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package base 18 | 19 | type Options struct { 20 | Console bool `yaml:"console" mapstructure:"console"` 21 | Verbose bool `yaml:"verbose" mapstructure:"verbose"` 22 | PProfPort int `yaml:"pprof-port" mapstructure:"pprof-port"` 23 | Tracing TracingConfig `yaml:"tracing" mapstructure:"tracing"` 24 | } 25 | 26 | // TracingConfig defines the configuration for OpenTelemetry tracing. 27 | type TracingConfig struct { 28 | // Addr is the address of the tracing collector. 29 | Addr string `yaml:"addr" mapstructure:"addr"` 30 | // ServiceName is the name of the service for tracing. 31 | ServiceName string `yaml:"service-name" mapstructure:"service-name"` 32 | } 33 | -------------------------------------------------------------------------------- /cmd/dependency/version_cmd.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dependency 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/spf13/cobra" 23 | 24 | "d7y.io/dragonfly/v2/version" 25 | ) 26 | 27 | var VersionCmd = &cobra.Command{ 28 | Use: "version", 29 | Short: "show version", 30 | Long: `show the version details of dragonfly.`, 31 | Args: cobra.NoArgs, 32 | DisableAutoGenTag: true, 33 | SilenceUsage: true, 34 | Run: func(cmd *cobra.Command, args []string) { 35 | fmt.Printf("MajorVersion:\t%s\n", version.Major) 36 | fmt.Printf("MinorVersion:\t%s\n", version.Minor) 37 | fmt.Printf("GitVersion:\t%s\n", version.GitVersion) 38 | fmt.Printf("GitCommit:\t%s\n", version.GitCommit) 39 | fmt.Printf("Platform:\t%s\n", version.Platform) 40 | fmt.Printf("BuildTime:\t%s\n", version.BuildTime) 41 | fmt.Printf("GoVersion:\t%s\n", version.GoVersion) 42 | fmt.Printf("Gotags: \t%s\n", version.Gotags) 43 | fmt.Printf("Gogcflags:\t%s\n", version.Gogcflags) 44 | }, 45 | } 46 | -------------------------------------------------------------------------------- /cmd/dfcache/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/cmd/dfcache/cmd" 21 | ) 22 | 23 | func main() { 24 | cmd.Execute() 25 | } 26 | -------------------------------------------------------------------------------- /cmd/dfget/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/cmd/dfget/cmd" 21 | ) 22 | 23 | func main() { 24 | cmd.Execute() 25 | } 26 | -------------------------------------------------------------------------------- /cmd/dfstore/cmd/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | "net/url" 23 | ) 24 | 25 | // Parse object storage url. 26 | func parseDfstoreURL(rawURL string) (string, string, error) { 27 | u, err := url.ParseRequestURI(rawURL) 28 | if err != nil { 29 | return "", "", err 30 | } 31 | 32 | if u.Scheme != DfstoreScheme { 33 | return "", "", fmt.Errorf("invalid scheme, e.g. %s://bucket_name/object_key", DfstoreScheme) 34 | } 35 | 36 | if u.Host == "" { 37 | return "", "", errors.New("invalid bucket name") 38 | } 39 | 40 | if u.Path == "" { 41 | return "", "", errors.New("invalid object key") 42 | } 43 | 44 | return u.Host, u.Path, nil 45 | } 46 | 47 | // isDfstoreURL determines whether the raw url is dfstore url. 48 | func isDfstoreURL(rawURL string) bool { 49 | u, err := url.ParseRequestURI(rawURL) 50 | if err != nil { 51 | return false 52 | } 53 | 54 | if u.Scheme != DfstoreScheme || u.Host == "" || u.Path == "" { 55 | return false 56 | } 57 | 58 | return true 59 | } 60 | -------------------------------------------------------------------------------- /cmd/dfstore/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import "d7y.io/dragonfly/v2/cmd/dfstore/cmd" 20 | 21 | func main() { 22 | cmd.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /cmd/manager/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/api/manager" 21 | "d7y.io/dragonfly/v2/cmd/manager/cmd" 22 | ) 23 | 24 | // @title Dragonfly Manager 25 | // @version 1.0.0 26 | // @description Dragonfly Manager Server 27 | // @contact.url https://d7y.io 28 | // @license.name Apache 2.0 29 | // @host localhost:8080 30 | // @BasePath / 31 | // @tag.name api 32 | // @tag.description API router (/api/v1) 33 | // @tag.name oapi 34 | // @tag.description open API router (/oapi/v1) 35 | func main() { 36 | cmd.Execute() 37 | } 38 | -------------------------------------------------------------------------------- /cmd/scheduler/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/cmd/scheduler/cmd" 21 | ) 22 | 23 | func main() { 24 | cmd.Execute() 25 | } 26 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | precision: 2 3 | round: down 4 | range: "80...100" 5 | status: 6 | project: 7 | default: 8 | enabled: yes 9 | target: 33% 10 | patch: 11 | default: 12 | enabled: no 13 | 14 | comment: 15 | layout: "reach, diff, flags, files" 16 | behavior: default 17 | require_changes: false 18 | branches: 19 | - main 20 | -------------------------------------------------------------------------------- /deploy/docker-compose/README.md: -------------------------------------------------------------------------------- 1 | # Deploying Dragonfly with Container Directly 2 | 3 | > Currently, docker compose deploying is tested just in single host, no HA support. 4 | 5 | ## Deploy with Docker Compose 6 | 7 | The `run.sh` script will generate config and deploy all components with `docker-compose`. 8 | 9 | Just run: 10 | 11 | ```shell 12 | # Without network=host mode,the HOST IP would be the docker network gateway IP address, use the command below to 13 | # obtain the ip address, "docker network inspect bridge -f '{{range .IPAM.Config}}{{.Gateway}}{{end}}'" 14 | export IP= 15 | ./run.sh 16 | ``` 17 | 18 | ## Delete containers with docker compose 19 | 20 | ```shell 21 | docker compose down 22 | ``` 23 | -------------------------------------------------------------------------------- /deploy/docker-compose/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | REPO=${REPO:-dragonflyoss} 6 | TAG=${TAG:-latest} 7 | CLIENT_TAG=${CLIENT_TAG:-latest} 8 | 9 | DIR=$(cd "$(dirname "$0")" && pwd) 10 | cd $DIR 11 | 12 | prepare(){ 13 | mkdir -p config 14 | 15 | ip=${IP:-$(hostname -i)} 16 | 17 | sed "s,__IP__,$ip," template/client.template.yaml > config/client.yaml 18 | sed "s,__IP__,$ip," template/seed-client.template.yaml > config/seed-client.yaml 19 | sed "s,__IP__,$ip," template/scheduler.template.yaml > config/scheduler.yaml 20 | sed "s,__IP__,$ip," template/manager.template.yaml > config/manager.yaml 21 | } 22 | 23 | run() { 24 | # start all of docker-compose defined service 25 | COMPOSE=docker-compose 26 | # use docker compose plugin 27 | if docker compose version; then 28 | COMPOSE="docker compose" 29 | fi 30 | 31 | $COMPOSE up -d 32 | 33 | # docker-compose version 3 depends_on does not wait for redis and mysql to be “ready” before starting manager ... 34 | # doc https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on 35 | for i in $(seq 0 10); do 36 | service_num=$($COMPOSE ps --services |wc -l) 37 | ready_num=$($COMPOSE ps | grep healthy | wc -l) 38 | if [ "$service_num" -eq "$ready_num" ]; then 39 | break 40 | fi 41 | echo "wait for all service ready: $ready_num/$service_num,$i times check" 42 | sleep 2 43 | done 44 | 45 | # print service list info 46 | $COMPOSE ps 47 | exit 0 48 | } 49 | 50 | prepare 51 | run 52 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Dragonfly Document 2 | 3 | You can find the full documentation on the [d7y.io](https://d7y.io). 4 | 5 | Welcome developers to contribute code to [d7y.io](https://d7y.io) and the source code repository is [dragonflyoss/d7y.io](https://github.com/dragonflyoss/d7y.io). 6 | -------------------------------------------------------------------------------- /docs/images/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/docs/images/arch.png -------------------------------------------------------------------------------- /docs/images/community/dingtalk-group.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/docs/images/community/dingtalk-group.jpeg -------------------------------------------------------------------------------- /docs/images/logo/dragonfly-linear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/docs/images/logo/dragonfly-linear.png -------------------------------------------------------------------------------- /docs/images/logo/dragonfly-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/docs/images/logo/dragonfly-vertical.png -------------------------------------------------------------------------------- /docs/security/dragonfly-comprehensive-report-2023.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/docs/security/dragonfly-comprehensive-report-2023.pdf -------------------------------------------------------------------------------- /hack/ca/.gitignore: -------------------------------------------------------------------------------- 1 | *.conf 2 | manager/ 3 | rootca/ -------------------------------------------------------------------------------- /hack/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o nounset 4 | set -o errexit 5 | set -o pipefail 6 | 7 | curDir=$(cd "$(dirname "$0")" && pwd) 8 | cd "${curDir}/../" || return 9 | 10 | D7Y_VERSION=${D7Y_VERSION:-"latest"} 11 | D7Y_REGISTRY=${D7Y_REGISTRY:-dragonflyoss} 12 | IMAGES_DIR="build/images" 13 | BASE_IMAGE=${BASE_IMAGE:-alpine:3.20} 14 | 15 | CGO_ENABLED=${CGO_ENABLED:-0} 16 | GOPROXY=${GOPROXY:-`go env GOPROXY`} 17 | GOTAGS=${GOTAGS:-} 18 | GOGCFLAGS=${GOGCFLAGS:-} 19 | 20 | GOOS=${GOOS:-linux} 21 | GOARCH=${GOARCH:-amd64} 22 | 23 | # enable bash debug output 24 | DEBUG=${DEBUG:-} 25 | 26 | if [[ -n "$DEBUG" ]]; then 27 | set -x 28 | fi 29 | 30 | docker-build() { 31 | name=$1 32 | docker build \ 33 | --platform ${GOOS}/${GOARCH} \ 34 | --build-arg CGO_ENABLED="${CGO_ENABLED}" \ 35 | --build-arg GOPROXY="${GOPROXY}" \ 36 | --build-arg GOTAGS="${GOTAGS}" \ 37 | --build-arg GOGCFLAGS="${GOGCFLAGS}" \ 38 | --build-arg BASE_IMAGE="${BASE_IMAGE}" \ 39 | -t "${D7Y_REGISTRY}/${name}:${D7Y_VERSION}" \ 40 | -f "${IMAGES_DIR}/${name}/Dockerfile" . 41 | } 42 | 43 | git-submodule() { 44 | git submodule update --init --recursive 45 | } 46 | 47 | main() { 48 | case "${1-}" in 49 | dfdaemon) 50 | docker-build dfdaemon 51 | ;; 52 | scheduler) 53 | docker-build scheduler 54 | ;; 55 | manager) 56 | git-submodule 57 | docker-build manager 58 | esac 59 | } 60 | 61 | main "$@" 62 | -------------------------------------------------------------------------------- /hack/docker-push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o nounset 4 | set -o errexit 5 | set -o pipefail 6 | 7 | D7Y_VERSION=${D7Y_VERSION:-"latest"} 8 | D7Y_REGISTRY=${D7Y_REGISTRY:-dragonflyoss} 9 | curDir=$(cd "$(dirname "$0")" && pwd) 10 | cd "${curDir}/../" || return 11 | 12 | docker-push() { 13 | docker push "${D7Y_REGISTRY}"/"${1}":"${D7Y_VERSION}" 14 | } 15 | 16 | main() { 17 | case "${1-}" in 18 | dfdaemon) 19 | docker-push dfdaemon 20 | ;; 21 | scheduler) 22 | docker-push scheduler 23 | ;; 24 | manager) 25 | docker-push manager 26 | esac 27 | } 28 | 29 | main "$@" 30 | -------------------------------------------------------------------------------- /hack/env.sh: -------------------------------------------------------------------------------- 1 | set -o nounset 2 | set -o errexit 3 | set -o pipefail 4 | 5 | export INSTALL_HOME=/opt/dragonfly 6 | export INSTALL_BIN_PATH=bin 7 | export GO_SOURCE_EXCLUDES=( \ 8 | "test" \ 9 | ) 10 | 11 | GOOS=$(go env GOOS) 12 | GOARCH=$(go env GOARCH) 13 | CGO_ENABLED=${CGO_ENABLED:-0} 14 | export GOOS 15 | export GOARCH 16 | export CGO_ENABLED 17 | -------------------------------------------------------------------------------- /hack/gen-containerd-hosts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # the register to pull image, like "docker.io", when pull image with "docker.io/library/alpine:latest" 4 | registry=${1:-${REGISTRY}} 5 | 6 | # the real server which serves image pulling, like "index.docker.io" 7 | # in normal case, registry_server is same with registry 8 | registry_server=${REGISTRY_SERVER:-${registry}} 9 | 10 | # dragonfly proxy url 11 | d7y_proxy=${2:-http://127.0.0.1:65001} 12 | 13 | if [[ -z "${registry}" ]]; then 14 | echo empty registry domain 15 | exit 1 16 | fi 17 | 18 | conf_dir=${CONTAINED_CONFIG_DIR:-/etc/containerd/certs.d} 19 | 20 | mkdir -p "$conf_dir/${registry}" 21 | 22 | cat << EOF > "$conf_dir/${registry}"/hosts.toml 23 | server = "https://${registry_server}" 24 | 25 | [host."${d7y_proxy}"] 26 | capabilities = ["pull", "resolve"] 27 | [host."${d7y_proxy}".header] 28 | X-Dragonfly-Registry = ["https://${registry_server}"] 29 | [host."https://${registry_server}"] 30 | capabilities = ["pull", "resolve"] 31 | EOF 32 | -------------------------------------------------------------------------------- /hack/kind-load.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o nounset 4 | set -o errexit 5 | set -o pipefail 6 | 7 | D7Y_VERSION=${D7Y_VERSION:-"latest"} 8 | D7Y_REGISTRY=${D7Y_REGISTRY:-dragonflyoss} 9 | 10 | kind-load() { 11 | kind load docker-image "${D7Y_REGISTRY}"/"${1}":"${D7Y_VERSION}" || { echo >&2 "load docker image error"; exit 1; } 12 | } 13 | 14 | main() { 15 | case "${1-}" in 16 | dfdaemon) 17 | kind-load dfdaemon 18 | ;; 19 | scheduler) 20 | kind-load scheduler 21 | ;; 22 | manager) 23 | kind-load manager 24 | esac 25 | } 26 | 27 | main "$@" 28 | -------------------------------------------------------------------------------- /hack/markdownlint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LINT_DIR=/data 4 | MARKDOWNLINT_IMAGE=avtodev/markdown-lint:v1 5 | 6 | docker run --rm \ 7 | -v "$(pwd):${LINT_DIR}:ro" \ 8 | ${MARKDOWNLINT_IMAGE} \ 9 | -c "${LINT_DIR}/.markdownlint.yml" /data/**/*.md \ 10 | -i "${LINT_DIR}/CHANGELOG.md" \ 11 | -i "${LINT_DIR}/build" \ 12 | -i "${LINT_DIR}/deploy/helm-charts" \ 13 | -i "${LINT_DIR}/manager/console" \ 14 | -------------------------------------------------------------------------------- /hack/update-version-gorelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GO_VERSION=$(go version | grep -o 'go[^ ].*') 4 | 5 | sed -i "s#\tGoVersion = ".*"#\tGoVersion = \"${GO_VERSION}\"#" version/version.go 6 | -------------------------------------------------------------------------------- /internal/dflog/signal.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package logger 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "os/signal" 23 | "syscall" 24 | 25 | "go.uber.org/zap" 26 | "go.uber.org/zap/zapcore" 27 | ) 28 | 29 | var ( 30 | levels []zap.AtomicLevel 31 | level = zapcore.InfoLevel 32 | ) 33 | 34 | func startLoggerSignalHandler() { 35 | signals := make(chan os.Signal, 1) 36 | signal.Notify(signals, syscall.SIGUSR1) 37 | 38 | go func() { 39 | for { 40 | select { 41 | case <-signals: 42 | level-- 43 | if level < zapcore.DebugLevel { 44 | level = zapcore.FatalLevel 45 | } 46 | 47 | // use fmt.Printf print change log level event when log level is greater than info level 48 | fmt.Printf("change log level to %s\n", level.String()) 49 | SetLevel(level) 50 | } 51 | } 52 | }() 53 | } 54 | -------------------------------------------------------------------------------- /internal/dynconfig/manager_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //go:generate mockgen -destination mocks/manager_client_mock.go -source manager_client.go -package mocks 18 | 19 | package dynconfig 20 | 21 | // managerClient is a client of manager. 22 | type ManagerClient interface { 23 | Get() (any, error) 24 | } 25 | -------------------------------------------------------------------------------- /internal/dynconfig/testdata/dynconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "scheduler": { 3 | "name": "foo" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /internal/job/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package job 18 | 19 | // Queue Name. 20 | const ( 21 | GlobalQueue = Queue("global") 22 | SchedulersQueue = Queue("schedulers") 23 | ) 24 | 25 | // Job Name. 26 | const ( 27 | // PreheatJob is the name of preheat job. 28 | PreheatJob = "preheat" 29 | 30 | // SyncPeersJob is the name of syncing peers job. 31 | SyncPeersJob = "sync_peers" 32 | 33 | // GetTaskJob is the name of getting task job. 34 | GetTaskJob = "get_task" 35 | 36 | // DeleteTaskJob is the name of deleting task job. 37 | DeleteTaskJob = "delete_task" 38 | 39 | // GCJob is the name of gc job. 40 | GCJob = "gc" 41 | ) 42 | 43 | // Machinery server configuration. 44 | const ( 45 | DefaultResultsExpireIn = 86400 46 | DefaultRedisMaxIdle = 30 47 | DefaultRedisMaxActive = 50 48 | DefaultRedisIdleTimeout = 30 49 | DefaultRedisReadTimeout = 60 50 | DefaultRedisWriteTimeout = 60 51 | DefaultRedisConnectTimeout = 60 52 | DefaultRedisNormalTasksPollPeriod = 2500 53 | DefaultRedisDelayedTasksPollPeriod = 500 54 | ) 55 | -------------------------------------------------------------------------------- /internal/job/logger.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | logger "d7y.io/dragonfly/v2/internal/dflog" 5 | ) 6 | 7 | type MachineryLogger struct{} 8 | 9 | // Print sends to logger.Info 10 | func (m *MachineryLogger) Print(args ...any) { 11 | logger.JobLogger.Info(args...) 12 | } 13 | 14 | // Printf sends to logger.Infof 15 | func (m *MachineryLogger) Printf(format string, args ...any) { 16 | logger.JobLogger.Infof(format, args...) 17 | } 18 | 19 | // Println sends to logger.Info 20 | func (m *MachineryLogger) Println(args ...any) { 21 | logger.JobLogger.Info(args...) 22 | } 23 | 24 | // Fatal sends to logger.Fatal 25 | func (m *MachineryLogger) Fatal(args ...any) { 26 | logger.JobLogger.Fatal(args...) 27 | } 28 | 29 | // Fatalf sends to logger.Fatalf 30 | func (m *MachineryLogger) Fatalf(format string, args ...any) { 31 | logger.JobLogger.Fatalf(format, args...) 32 | } 33 | 34 | // Fatalln sends to logger.Fatal 35 | func (m *MachineryLogger) Fatalln(args ...any) { 36 | logger.JobLogger.Fatal(args...) 37 | } 38 | 39 | // Panic sends to logger.Panic 40 | func (m *MachineryLogger) Panic(args ...any) { 41 | logger.JobLogger.Panic(args...) 42 | } 43 | 44 | // Panicf sends to logger.Panic 45 | func (m *MachineryLogger) Panicf(format string, args ...any) { 46 | logger.JobLogger.Panic(args...) 47 | } 48 | 49 | // Panicln sends to logger.Panic 50 | func (m *MachineryLogger) Panicln(args ...any) { 51 | logger.JobLogger.Panic(args...) 52 | } 53 | -------------------------------------------------------------------------------- /internal/job/queue.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package job 18 | 19 | import ( 20 | "errors" 21 | "fmt" 22 | ) 23 | 24 | type Queue string 25 | 26 | func GetSchedulerQueue(clusterID uint, hostname string) (Queue, error) { 27 | if clusterID == 0 { 28 | return Queue(""), errors.New("empty cluster id config is not specified") 29 | } 30 | 31 | if hostname == "" { 32 | return Queue(""), errors.New("empty hostname config is not specified") 33 | } 34 | 35 | return Queue(fmt.Sprintf("scheduler_%d_%s", clusterID, hostname)), nil 36 | } 37 | 38 | func (q Queue) String() string { 39 | return string(q) 40 | } 41 | -------------------------------------------------------------------------------- /internal/util/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package util 18 | 19 | import "math" 20 | 21 | const ( 22 | // DefaultPieceSize 4M 23 | DefaultPieceSize = 4 * 1024 * 1024 24 | 25 | // DefaultPieceSizeLimit 15M 26 | DefaultPieceSizeLimit = 15 * 1024 * 1024 27 | ) 28 | 29 | // ComputePieceSize computes the piece size with specified fileLength. 30 | // 31 | // If the fileLength < 0, which means failed to get fileLength 32 | // and then use the DefaultPieceSize. 33 | func ComputePieceSize(length int64) uint32 { 34 | if length <= 200*1024*1024 { 35 | return DefaultPieceSize 36 | } 37 | 38 | gapCount := length / int64(100*1024*1024) 39 | mpSize := (gapCount-2)*1024*1024 + DefaultPieceSize 40 | if mpSize > DefaultPieceSizeLimit { 41 | return DefaultPieceSizeLimit 42 | } 43 | return uint32(mpSize) 44 | } 45 | 46 | // ComputePieceCount returns piece count with given length and pieceSize 47 | func ComputePieceCount(length int64, pieceSize uint32) int32 { 48 | return int32(math.Ceil(float64(length) / float64(pieceSize))) 49 | } 50 | -------------------------------------------------------------------------------- /manager/auth/oauth/oauth.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //go:generate mockgen -destination mocks/oauth_mock.go -source oauth.go -package mocks 18 | 19 | package oauth 20 | 21 | import ( 22 | "errors" 23 | "time" 24 | 25 | "golang.org/x/oauth2" 26 | ) 27 | 28 | const ( 29 | // default timeout for oauth 30 | timeout = 2 * time.Minute 31 | ) 32 | 33 | const ( 34 | Google = "google" 35 | Github = "github" 36 | ) 37 | 38 | type User struct { 39 | Name string 40 | Email string 41 | Avatar string 42 | } 43 | 44 | // Oauth interface for oauth2 45 | type Oauth interface { 46 | AuthCodeURL() (string, error) 47 | Exchange(string) (*oauth2.Token, error) 48 | GetUser(*oauth2.Token) (*User, error) 49 | } 50 | 51 | func New(name, clientID, clientSecret, redirectURL string) (Oauth, error) { 52 | var o Oauth 53 | switch name { 54 | case Google: 55 | o = newGoogle(clientID, clientSecret, redirectURL) 56 | case Github: 57 | o = newGithub(clientID, clientSecret, redirectURL) 58 | default: 59 | return nil, errors.New("invalid oauth name") 60 | } 61 | 62 | return o, nil 63 | } 64 | -------------------------------------------------------------------------------- /manager/config/constant_otel.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | import "go.opentelemetry.io/otel/attribute" 20 | 21 | const ( 22 | AttributeID = attribute.Key("d7y.manager.id") 23 | AttributePreheatType = attribute.Key("d7y.manager.preheat.type") 24 | AttributePreheatURL = attribute.Key("d7y.manager.preheat.url") 25 | AttributeDeleteTaskID = attribute.Key("d7y.manager.delete_task.id") 26 | AttributeGetTaskID = attribute.Key("d7y.manager.get_task.id") 27 | ) 28 | 29 | const ( 30 | SpanPreheat = "preheat" 31 | SpanSyncPeers = "sync-peers" 32 | SpanGetLayers = "get-layers" 33 | SpanAuthWithRegistry = "auth-with-registry" 34 | SpanDeleteTask = "delete-task" 35 | SpanGetTask = "get-task" 36 | ) 37 | -------------------------------------------------------------------------------- /manager/config/testdata/ca.crt: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /manager/config/testdata/ca.key: -------------------------------------------------------------------------------- 1 | bar 2 | -------------------------------------------------------------------------------- /manager/dist/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dragonflyoss/dragonfly/9f1f66a55b05dcd48cd55537bd3e44e90e70494a/manager/dist/.gitkeep -------------------------------------------------------------------------------- /manager/handlers/health.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package handlers 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/gin-gonic/gin" 23 | ) 24 | 25 | // @Summary Get Health 26 | // @Description Get app health 27 | // @Tags Health 28 | // @Accept json 29 | // @Produce json 30 | // @Success 200 31 | // @Failure 400 32 | // @Failure 404 33 | // @Failure 500 34 | // @Router /healthy [get] 35 | func (h *Handlers) GetHealth(ctx *gin.Context) { 36 | ctx.JSON(http.StatusOK, http.StatusText(http.StatusOK)) 37 | } 38 | -------------------------------------------------------------------------------- /manager/handlers/permission.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package handlers 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/gin-gonic/gin" 23 | 24 | // nolint 25 | _ "d7y.io/dragonfly/v2/manager/permission/rbac" 26 | ) 27 | 28 | // @Summary Get Permissions 29 | // @Description Get Permissions 30 | // @Tags Permission 31 | // @Produce json 32 | // @Success 200 {object} []rbac.Permission 33 | // @Failure 400 34 | // @Failure 500 35 | // @Router /api/v1/permissions [get] 36 | func (h *Handlers) GetPermissions(g *gin.Engine) func(ctx *gin.Context) { 37 | return func(ctx *gin.Context) { 38 | ctx.JSON(http.StatusOK, h.service.GetPermissions(ctx.Request.Context(), g)) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /manager/handlers/scheduler_feature.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package handlers 18 | 19 | import ( 20 | "net/http" 21 | 22 | "github.com/gin-gonic/gin" 23 | 24 | // nolint 25 | _ "d7y.io/dragonfly/v2/manager/models" 26 | ) 27 | 28 | // @Summary Get Scheudler Features 29 | // @Description Get Scheduler Features 30 | // @Tags Scheduler Feature 31 | // @Accept json 32 | // @Produce json 33 | // @Success 200 {array} string 34 | // @Failure 400 35 | // @Failure 404 36 | // @Failure 500 37 | // @Router /api/v1/scheduler-features [get] 38 | func (h *Handlers) GetSchedulerFeatures(ctx *gin.Context) { 39 | features := h.service.GetSchedulerFeatures(ctx.Request.Context()) 40 | ctx.JSON(http.StatusOK, features) 41 | } 42 | -------------------------------------------------------------------------------- /manager/job/preheat_test.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | 9 | internaljob "d7y.io/dragonfly/v2/internal/job" 10 | "d7y.io/dragonfly/v2/manager/types" 11 | ) 12 | 13 | func TestPreheat_getImageLayers(t *testing.T) { 14 | tests := []struct { 15 | name string 16 | args types.PreheatArgs 17 | expect func(t *testing.T, layers []internaljob.PreheatRequest) 18 | }{ 19 | { 20 | name: "get image layers with manifest url", 21 | args: types.PreheatArgs{ 22 | URL: "https://registry-1.docker.io/v2/dragonflyoss/busybox/manifests/1.35.0", 23 | Type: "image", 24 | }, 25 | expect: func(t *testing.T, layers []internaljob.PreheatRequest) { 26 | assert := assert.New(t) 27 | assert.Equal(2, len(layers)) 28 | }, 29 | }, 30 | { 31 | name: "get image layers with multi arch image layers", 32 | args: types.PreheatArgs{ 33 | URL: "https://registry-1.docker.io/v2/dragonflyoss/scheduler/manifests/v2.1.0", 34 | Platform: "linux/amd64", 35 | }, 36 | expect: func(t *testing.T, layers []internaljob.PreheatRequest) { 37 | assert := assert.New(t) 38 | assert.Equal(5, len(layers)) 39 | }, 40 | }, 41 | } 42 | 43 | for _, tc := range tests { 44 | t.Run(tc.name, func(t *testing.T) { 45 | p := &preheat{} 46 | layers, err := p.getImageLayers(context.Background(), tc.args) 47 | if err != nil { 48 | t.Fatal(err) 49 | } 50 | 51 | tc.expect(t, layers) 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /manager/job/types.go: -------------------------------------------------------------------------------- 1 | package job 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "regexp" 7 | ) 8 | 9 | // accessURLRegexp is the regular expression for parsing access url. 10 | var accessURLRegexp, _ = regexp.Compile("^(.*)://(.*)/v2/(.*)/manifests/(.*)") 11 | 12 | // preheatImage is image information for preheat. 13 | type preheatImage struct { 14 | protocol string 15 | domain string 16 | name string 17 | tag string 18 | } 19 | 20 | func (p *preheatImage) manifestURL() string { 21 | return fmt.Sprintf("%s://%s/v2/%s/manifests/%s", p.protocol, p.domain, p.name, p.tag) 22 | } 23 | 24 | func (p *preheatImage) blobsURL(digest string) string { 25 | return fmt.Sprintf("%s://%s/v2/%s/blobs/%s", p.protocol, p.domain, p.name, digest) 26 | } 27 | 28 | // parseManifestURL parses manifest url. 29 | func parseManifestURL(url string) (*preheatImage, error) { 30 | r := accessURLRegexp.FindStringSubmatch(url) 31 | if len(r) != 5 { 32 | return nil, errors.New("parse access url failed") 33 | } 34 | 35 | return &preheatImage{ 36 | protocol: r[1], 37 | domain: r[2], 38 | name: r[3], 39 | tag: r[4], 40 | }, nil 41 | } 42 | -------------------------------------------------------------------------------- /manager/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package metrics 18 | 19 | import ( 20 | "net/http" 21 | "testing" 22 | 23 | "google.golang.org/grpc" 24 | 25 | "d7y.io/dragonfly/v2/manager/config" 26 | ) 27 | 28 | func TestNew(t *testing.T) { 29 | cfg := &config.MetricsConfig{ 30 | Addr: "localhost:8080", 31 | } 32 | svr := grpc.NewServer() 33 | server := New(cfg, svr) 34 | 35 | if server.Addr != cfg.Addr { 36 | t.Errorf("expected server.Addr to be %s, but got %s", cfg.Addr, server.Addr) 37 | } 38 | 39 | if _, ok := server.Handler.(*http.ServeMux); !ok { 40 | t.Errorf("expected server.Handler to be a *http.ServeMux, but got %T", server.Handler) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /manager/middlewares/ratelimiter.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package middlewares 18 | 19 | import ( 20 | "net/http" 21 | 22 | "d7y.io/dragonfly/v2/internal/ratelimiter" 23 | "d7y.io/dragonfly/v2/manager/types" 24 | "github.com/gin-gonic/gin" 25 | "github.com/gin-gonic/gin/binding" 26 | ) 27 | 28 | // CreateJobRateLimiter create job rate limiter middleware 29 | func CreateJobRateLimiter(limiter ratelimiter.JobRateLimiter) gin.HandlerFunc { 30 | return func(c *gin.Context) { 31 | var json types.CreateJobRequest 32 | if err := c.ShouldBindBodyWith(&json, binding.JSON); err != nil { 33 | c.JSON(http.StatusUnprocessableEntity, gin.H{"errors": err.Error()}) 34 | return 35 | } 36 | 37 | if allowed := limiter.AllowByClusterIDs(c, json.SchedulerClusterIDs); !allowed { 38 | c.String(http.StatusTooManyRequests, "rate limit exceeded") 39 | c.Abort() 40 | return 41 | } 42 | 43 | c.Next() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /manager/middlewares/server.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package middlewares 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/gin-gonic/gin" 23 | 24 | "d7y.io/dragonfly/v2/pkg/net/ip" 25 | ) 26 | 27 | const ServerIP = "X-Server-IP" 28 | 29 | func Server() gin.HandlerFunc { 30 | return func(c *gin.Context) { 31 | c.Header(ServerIP, fmt.Sprintf("%s, %s", ip.IPv4.String(), ip.IPv6.String())) 32 | c.Next() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /manager/models/application.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package models 18 | 19 | type Application struct { 20 | BaseModel 21 | Name string `gorm:"column:name;type:varchar(256);index:uk_application_name,unique;not null;comment:name" json:"name"` 22 | URL string `gorm:"column:url;not null;comment:url" json:"url"` 23 | BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"` 24 | Priority JSONMap `gorm:"column:priority;not null;comment:download priority" json:"priority"` 25 | UserID uint `gorm:"comment:user id" json:"user_id"` 26 | User User `json:"user"` 27 | } 28 | -------------------------------------------------------------------------------- /manager/models/casbin_rule.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package models 18 | 19 | type CasbinRule struct { 20 | ID uint `gorm:"primaryKey;autoIncrement;comment:id"` 21 | Ptype string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:policy type"` 22 | V0 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v0"` 23 | V1 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v1"` 24 | V2 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v2"` 25 | V3 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v3"` 26 | V4 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v4"` 27 | V5 string `gorm:"type:varchar(100);default:NULL;uniqueIndex:uk_casbin_rule;comment:v5"` 28 | } 29 | -------------------------------------------------------------------------------- /manager/models/oauth.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package models 18 | 19 | type Oauth struct { 20 | BaseModel 21 | Name string `gorm:"column:name;type:varchar(256);index:uk_oauth2_name,unique;not null;comment:oauth2 name" json:"name"` 22 | BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"` 23 | ClientID string `gorm:"column:client_id;type:varchar(256);index:uk_oauth2_client_id,unique;not null;comment:client id for oauth2" json:"client_id"` 24 | ClientSecret string `gorm:"column:client_secret;type:varchar(1024);not null;comment:client secret for oauth2" json:"client_secret"` 25 | RedirectURL string `gorm:"column:redirect_url;type:varchar(1024);comment:authorization callback url" json:"redirect_url"` 26 | } 27 | -------------------------------------------------------------------------------- /manager/models/seed_peer_cluster.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package models 18 | 19 | type SeedPeerCluster struct { 20 | BaseModel 21 | Name string `gorm:"column:name;type:varchar(256);index:uk_seed_peer_cluster_name,unique;not null;comment:name" json:"name"` 22 | BIO string `gorm:"column:bio;type:varchar(1024);comment:biography" json:"bio"` 23 | Config JSONMap `gorm:"column:config;not null;comment:configuration" json:"config"` 24 | SchedulerClusters []SchedulerCluster `gorm:"many2many:seed_peer_cluster_scheduler_cluster;" json:"scheduler_clusters"` 25 | SeedPeers []SeedPeer `json:"seed_peer"` 26 | Jobs []Job `gorm:"many2many:job_seed_peer_cluster;" json:"jobs"` 27 | } 28 | -------------------------------------------------------------------------------- /manager/searcher/plugin.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package searcher 18 | 19 | import ( 20 | "errors" 21 | 22 | "d7y.io/dragonfly/v2/internal/dfplugin" 23 | ) 24 | 25 | const ( 26 | pluginName = "searcher" 27 | ) 28 | 29 | func LoadPlugin(dir string) (Searcher, error) { 30 | client, _, err := dfplugin.Load(dir, dfplugin.PluginTypeManager, pluginName, map[string]string{}) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | if rc, ok := client.(Searcher); ok { 36 | return rc, err 37 | } 38 | return nil, errors.New("invalid searcher plugin") 39 | } 40 | -------------------------------------------------------------------------------- /manager/searcher/testdata/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | 24 | logger "d7y.io/dragonfly/v2/internal/dflog" 25 | "d7y.io/dragonfly/v2/manager/models" 26 | "d7y.io/dragonfly/v2/manager/searcher" 27 | ) 28 | 29 | func main() { 30 | s, err := searcher.LoadPlugin("./testdata") 31 | if err != nil { 32 | fmt.Printf("load plugin error: %s\n", err) 33 | os.Exit(1) 34 | } 35 | 36 | clusters, err := s.FindSchedulerClusters(context.Background(), []models.SchedulerCluster{}, "127.0.0.1", "foo", map[string]string{}, logger.CoreLogger) 37 | if err != nil { 38 | fmt.Println("scheduler cluster not found") 39 | os.Exit(1) 40 | } 41 | 42 | if clusters[0].Name != "foo" { 43 | fmt.Println("scheduler cluster name wrong") 44 | os.Exit(1) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /manager/searcher/testdata/plugin/searcher.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "context" 21 | 22 | "go.uber.org/zap" 23 | 24 | "d7y.io/dragonfly/v2/manager/models" 25 | ) 26 | 27 | type searcher struct{} 28 | 29 | func (s *searcher) FindSchedulerClusters(ctx context.Context, schedulerClusters []models.SchedulerCluster, hostname, ip string, 30 | conditions map[string]string, log *zap.SugaredLogger) ([]models.SchedulerCluster, error) { 31 | return []models.SchedulerCluster{{Name: "foo"}}, nil 32 | } 33 | 34 | func DragonflyPluginInit(option map[string]string) (any, map[string]string, error) { 35 | return &searcher{}, map[string]string{"type": "manager", "name": "searcher"}, nil 36 | } 37 | -------------------------------------------------------------------------------- /manager/service/permission.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package service 18 | 19 | import ( 20 | "context" 21 | 22 | "github.com/gin-gonic/gin" 23 | 24 | "d7y.io/dragonfly/v2/manager/permission/rbac" 25 | ) 26 | 27 | func (s *service) GetPermissions(ctx context.Context, g *gin.Engine) []rbac.Permission { 28 | return rbac.GetPermissions(g) 29 | } 30 | -------------------------------------------------------------------------------- /manager/service/scheduler_feature.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package service 18 | 19 | import ( 20 | "context" 21 | 22 | "d7y.io/dragonfly/v2/manager/types" 23 | ) 24 | 25 | func (s *service) GetSchedulerFeatures(ctx context.Context) []string { 26 | return types.DefaultSchedulerFeatures 27 | } 28 | -------------------------------------------------------------------------------- /manager/types/bucket.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | type BucketParams struct { 20 | ID string `uri:"id" binding:"required"` 21 | } 22 | 23 | type CreateBucketRequest struct { 24 | Name string `json:"name" binding:"required"` 25 | } 26 | -------------------------------------------------------------------------------- /manager/types/preheat.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | type CreateV1PreheatRequest struct { 20 | Type string `json:"type" binding:"required,oneof=image file"` 21 | URL string `json:"url" binding:"required"` 22 | FilteredQueryParams string `json:"filteredQueryParams" binding:"omitempty"` 23 | Headers map[string]string `json:"headers" binding:"omitempty"` 24 | } 25 | 26 | type CreateV1PreheatResponse struct { 27 | ID string `json:"id"` 28 | } 29 | 30 | type GetV1PreheatResponse struct { 31 | ID string `json:"id"` 32 | Status string `json:"status"` 33 | StartTime string `json:"startTime,omitempty"` 34 | FinishTime string `json:"finishTime,omitempty"` 35 | } 36 | 37 | type V1PreheatParams struct { 38 | ID string `uri:"id" binding:"required"` 39 | } 40 | -------------------------------------------------------------------------------- /manager/types/role.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/manager/permission/rbac" 21 | ) 22 | 23 | type CreateRoleRequest struct { 24 | Role string `json:"role" binding:"required"` 25 | Permissions []rbac.Permission `json:"permissions" binding:"required"` 26 | } 27 | 28 | type RoleParams struct { 29 | Role string `uri:"role" binding:"required"` 30 | } 31 | 32 | type AddPermissionForRoleRequest struct { 33 | rbac.Permission `json:",inline" binding:"required"` 34 | } 35 | 36 | type DeletePermissionForRoleRequest struct { 37 | rbac.Permission `json:",inline" binding:"required"` 38 | } 39 | -------------------------------------------------------------------------------- /manager/types/scheduler_feature.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2024 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | const ( 20 | // SchedulerFeatureSchedule is the schedule feature of scheduler. 21 | SchedulerFeatureSchedule = "schedule" 22 | 23 | // SchedulerFeaturePreheat is the preheat feature of scheduler. 24 | SchedulerFeaturePreheat = "preheat" 25 | ) 26 | 27 | var ( 28 | // DefaultSchedulerFeatures is the default features of scheduler. 29 | DefaultSchedulerFeatures = []string{SchedulerFeatureSchedule, SchedulerFeaturePreheat} 30 | ) 31 | -------------------------------------------------------------------------------- /pkg/container/ring/queue.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ring 18 | 19 | type Queue[T any] interface { 20 | Enqueue(value *T) 21 | Dequeue() (value *T, ok bool) 22 | Close() 23 | } 24 | -------------------------------------------------------------------------------- /pkg/dfpath/dfpath_darwin.go: -------------------------------------------------------------------------------- 1 | //go:build darwin 2 | 3 | /* 4 | * Copyright 2020 The Dragonfly Authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package dfpath 20 | 21 | import ( 22 | "os" 23 | "path/filepath" 24 | 25 | "d7y.io/dragonfly/v2/pkg/os/user" 26 | ) 27 | 28 | var ( 29 | DefaultWorkHome = filepath.Join(user.HomeDir(), ".dragonfly") 30 | DefaultWorkHomeMode = os.FileMode(0700) 31 | DefaultCacheDir = filepath.Join(DefaultWorkHome, "cache") 32 | DefaultCacheDirMode = os.FileMode(0700) 33 | DefaultConfigDir = filepath.Join(DefaultWorkHome, "config") 34 | DefaultLogDir = filepath.Join(DefaultWorkHome, "logs") 35 | DefaultDataDir = filepath.Join(DefaultWorkHome, "data") 36 | DefaultDataDirMode = os.FileMode(0700) 37 | DefaultPluginDir = filepath.Join(DefaultWorkHome, "plugins") 38 | DefaultDownloadUnixSocketPath = filepath.Join(DefaultWorkHome, "dfdaemon.sock") 39 | ) 40 | -------------------------------------------------------------------------------- /pkg/dfpath/dfpath_linux.go: -------------------------------------------------------------------------------- 1 | //go:build linux 2 | 3 | /* 4 | * Copyright 2020 The Dragonfly Authors 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package dfpath 20 | 21 | import "os" 22 | 23 | var ( 24 | DefaultWorkHome = "/usr/local/dragonfly" 25 | DefaultWorkHomeMode = os.FileMode(0700) 26 | DefaultCacheDir = "/var/cache/dragonfly" 27 | DefaultCacheDirMode = os.FileMode(0700) 28 | DefaultConfigDir = "/etc/dragonfly" 29 | DefaultLogDir = "/var/log/dragonfly" 30 | DefaultDataDir = "/var/lib/dragonfly" 31 | DefaultDataDirMode = os.FileMode(0700) 32 | DefaultPluginDir = "/usr/local/dragonfly/plugins" 33 | DefaultDownloadUnixSocketPath = "/var/run/dfdaemon.sock" 34 | ) 35 | -------------------------------------------------------------------------------- /pkg/gc/logger.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //go:generate mockgen -destination logger_mock.go -source logger.go -package gc 18 | 19 | package gc 20 | 21 | import ( 22 | logger "d7y.io/dragonfly/v2/internal/dflog" 23 | ) 24 | 25 | // Logger is the interface used in GC for logging. 26 | type Logger interface { 27 | // Infof logs routine messages for GC. 28 | Infof(template string, args ...any) 29 | // Error logs error messages for GC. 30 | Errorf(template string, args ...any) 31 | } 32 | 33 | // gcLogger is default logger of dflog. 34 | type gcLogger struct{} 35 | 36 | // Infof logs routine messages for GC. 37 | func (gl *gcLogger) Infof(template string, args ...any) { 38 | logger.CoreLogger.Infof(template, args) 39 | } 40 | 41 | // Error logs error messages for GC. 42 | func (gl *gcLogger) Errorf(template string, args ...any) { 43 | logger.CoreLogger.Errorf(template, args) 44 | } 45 | -------------------------------------------------------------------------------- /pkg/gc/runner_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: task.go 3 | // 4 | // Generated by this command: 5 | // 6 | // mockgen -destination runner_mock.go -source task.go -package gc 7 | // 8 | 9 | // Package gc is a generated GoMock package. 10 | package gc 11 | 12 | import ( 13 | context "context" 14 | reflect "reflect" 15 | 16 | gomock "go.uber.org/mock/gomock" 17 | ) 18 | 19 | // MockRunner is a mock of Runner interface. 20 | type MockRunner struct { 21 | ctrl *gomock.Controller 22 | recorder *MockRunnerMockRecorder 23 | isgomock struct{} 24 | } 25 | 26 | // MockRunnerMockRecorder is the mock recorder for MockRunner. 27 | type MockRunnerMockRecorder struct { 28 | mock *MockRunner 29 | } 30 | 31 | // NewMockRunner creates a new mock instance. 32 | func NewMockRunner(ctrl *gomock.Controller) *MockRunner { 33 | mock := &MockRunner{ctrl: ctrl} 34 | mock.recorder = &MockRunnerMockRecorder{mock} 35 | return mock 36 | } 37 | 38 | // EXPECT returns an object that allows the caller to indicate expected use. 39 | func (m *MockRunner) EXPECT() *MockRunnerMockRecorder { 40 | return m.recorder 41 | } 42 | 43 | // RunGC mocks base method. 44 | func (m *MockRunner) RunGC(arg0 context.Context) error { 45 | m.ctrl.T.Helper() 46 | ret := m.ctrl.Call(m, "RunGC", arg0) 47 | ret0, _ := ret[0].(error) 48 | return ret0 49 | } 50 | 51 | // RunGC indicates an expected call of RunGC. 52 | func (mr *MockRunnerMockRecorder) RunGC(arg0 any) *gomock.Call { 53 | mr.mock.ctrl.T.Helper() 54 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunGC", reflect.TypeOf((*MockRunner)(nil).RunGC), arg0) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/gc/task.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //go:generate mockgen -destination runner_mock.go -source task.go -package gc 18 | 19 | package gc 20 | 21 | import ( 22 | "context" 23 | "errors" 24 | "time" 25 | ) 26 | 27 | type Runner interface { 28 | RunGC(context.Context) error 29 | } 30 | 31 | // Task is an struct used to run GC instance. 32 | type Task struct { 33 | ID string 34 | Interval time.Duration 35 | Timeout time.Duration 36 | Runner Runner 37 | } 38 | 39 | // Validate task params. 40 | func (t *Task) validate() error { 41 | if t.ID == "" { 42 | return errors.New("empty ID is not specified") 43 | } 44 | 45 | if t.Interval <= 0 { 46 | return errors.New("Interval value is greater than 0") 47 | } 48 | 49 | if t.Timeout <= 0 { 50 | return errors.New("Timeout value is greater than 0") 51 | } 52 | 53 | if t.Timeout > t.Interval { 54 | return errors.New("Timeout value needs to be less than the Interval value") 55 | } 56 | 57 | if t.Runner == nil { 58 | return errors.New("empty Runner is not specified") 59 | } 60 | 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /pkg/graph/dag/vertex.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dag 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/pkg/container/set" 21 | ) 22 | 23 | // Vertex is a vertex of the directed acyclic graph. 24 | type Vertex[T comparable] struct { 25 | ID string 26 | Value T 27 | Parents set.Set[*Vertex[T]] 28 | Children set.Set[*Vertex[T]] 29 | } 30 | 31 | // New returns a new Vertex instance. 32 | func NewVertex[T comparable](id string, value T) *Vertex[T] { 33 | return &Vertex[T]{ 34 | ID: id, 35 | Value: value, 36 | Parents: set.New[*Vertex[T]](), 37 | Children: set.New[*Vertex[T]](), 38 | } 39 | } 40 | 41 | // Degree returns the degree of vertex. 42 | func (v *Vertex[T]) Degree() int { 43 | return int(v.Parents.Len() + v.Children.Len()) 44 | } 45 | 46 | // InDegree returns the indegree of vertex. 47 | func (v *Vertex[T]) InDegree() int { 48 | return int(v.Parents.Len()) 49 | } 50 | 51 | // OutDegree returns the outdegree of vertex. 52 | func (v *Vertex[T]) OutDegree() int { 53 | return int(v.Children.Len()) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/graph/dg/vertex.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package dg 18 | 19 | import ( 20 | "d7y.io/dragonfly/v2/pkg/container/set" 21 | ) 22 | 23 | // Vertex is a vertex of the directed graph. 24 | type Vertex[T comparable] struct { 25 | ID string 26 | Value T 27 | Parents set.Set[*Vertex[T]] 28 | Children set.Set[*Vertex[T]] 29 | } 30 | 31 | // New returns a new Vertex instance. 32 | func NewVertex[T comparable](id string, value T) *Vertex[T] { 33 | return &Vertex[T]{ 34 | ID: id, 35 | Value: value, 36 | Parents: set.New[*Vertex[T]](), 37 | Children: set.New[*Vertex[T]](), 38 | } 39 | } 40 | 41 | // Degree returns the degree of vertex. 42 | func (v *Vertex[T]) Degree() int { 43 | return int(v.Parents.Len() + v.Children.Len()) 44 | } 45 | 46 | // InDegree returns the indegree of vertex. 47 | func (v *Vertex[T]) InDegree() int { 48 | return int(v.Parents.Len()) 49 | } 50 | 51 | // OutDegree returns the outdegree of vertex. 52 | func (v *Vertex[T]) OutDegree() int { 53 | return int(v.Children.Len()) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/idgen/host_id.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package idgen 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | // HostIDV1 generates v1 version of host id. 24 | func HostIDV1(hostname string, port int32) string { 25 | return fmt.Sprintf("%s-%d", hostname, port) 26 | } 27 | 28 | // HostIDV2 generates v2 version of host id. 29 | func HostIDV2(ip, hostname string, isSeedPeer bool) string { 30 | if isSeedPeer { 31 | return fmt.Sprintf("%s-%s-seed", ip, hostname) 32 | } 33 | 34 | return fmt.Sprintf("%s-%s", ip, hostname) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/idgen/peer_id.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package idgen 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | 23 | "github.com/google/uuid" 24 | ) 25 | 26 | // PeerIDV1 generates v1 version of peer id. 27 | func PeerIDV1(ip string) string { 28 | return fmt.Sprintf("%s-%d-%s", ip, os.Getpid(), uuid.New()) 29 | } 30 | 31 | // SeedPeerIDV1 generates v1 version of seed peer id. 32 | func SeedPeerIDV1(ip string) string { 33 | return fmt.Sprintf("%s_%s", PeerIDV1(ip), "Seed") 34 | } 35 | 36 | // PeerIDV2 generates v2 version of peer id. 37 | func PeerIDV2() string { 38 | return uuid.NewString() 39 | } 40 | -------------------------------------------------------------------------------- /pkg/log/log.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package log 18 | 19 | import ( 20 | "go.uber.org/zap/zapcore" 21 | 22 | logger "d7y.io/dragonfly/v2/internal/dflog" 23 | "d7y.io/dragonfly/v2/pkg/dfpath" 24 | ) 25 | 26 | // SetCoreLevel sets core log level, export internal SetCoreLevel for using dragonfly as library 27 | func SetCoreLevel(level zapcore.Level) { 28 | logger.SetCoreLevel(level) 29 | } 30 | 31 | // SetGrpcLevel sets grpc log level, export internal SetGrpcLevel for using dragonfly as library 32 | func SetGrpcLevel(level zapcore.Level) { 33 | logger.SetGrpcLevel(level) 34 | } 35 | 36 | // SetupDaemon sets daemon log config: path, console 37 | func SetupDaemon(logDir string, verbose bool, console bool, rotateConfig logger.LogRotateConfig) error { 38 | var options []dfpath.Option 39 | if logDir != "" { 40 | options = append(options, dfpath.WithLogDir(logDir)) 41 | } 42 | 43 | d, err := dfpath.New(options...) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | return logger.InitDaemon(verbose, console, d.LogDir(), rotateConfig) 49 | } 50 | -------------------------------------------------------------------------------- /pkg/math/math.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package math 18 | -------------------------------------------------------------------------------- /pkg/net/fqdn/fqdn.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package fqdn 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/Showmax/go-fqdn" 23 | 24 | logger "d7y.io/dragonfly/v2/internal/dflog" 25 | ) 26 | 27 | var FQDNHostname string 28 | 29 | func init() { 30 | FQDNHostname = fqdnHostname() 31 | } 32 | 33 | // Get FQDN hostname 34 | func fqdnHostname() string { 35 | fqdn, err := fqdn.FqdnHostname() 36 | if err != nil { 37 | logger.Warnf("can not found fqdn: %s", err.Error()) 38 | hostname, err := os.Hostname() 39 | if err != nil { 40 | panic(err) 41 | } 42 | 43 | return hostname 44 | } 45 | 46 | return fqdn 47 | } 48 | -------------------------------------------------------------------------------- /pkg/net/fqdn/fqdn_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package fqdn 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestFQDNHostname(t *testing.T) { 26 | fqdn := fqdnHostname() 27 | assert.NotEmpty(t, fqdn) 28 | } 29 | -------------------------------------------------------------------------------- /pkg/net/ip/ip.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ip 18 | 19 | import "net" 20 | 21 | // FormatIP returns a valid textual representation of an IP address. 22 | func FormatIP(addr string) (string, bool) { 23 | ip := net.ParseIP(addr) 24 | if ip == nil { 25 | return "", false 26 | } 27 | 28 | if ip.To4() != nil { 29 | return addr, true 30 | } 31 | 32 | return "[" + addr + "]", true 33 | } 34 | -------------------------------------------------------------------------------- /pkg/net/ip/ip_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ip 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | ) 26 | 27 | func TestFormatIP(t *testing.T) { 28 | ip, ok := FormatIP(net.IPv6loopback.String()) 29 | assert.True(t, ok) 30 | assert.Equal(t, fmt.Sprintf("[%s]", net.IPv6loopback.String()), ip) 31 | 32 | ip, ok = FormatIP(net.IPv4zero.String()) 33 | assert.True(t, ok) 34 | assert.Equal(t, net.IPv4zero.String(), ip) 35 | 36 | _, ok = FormatIP("foo") 37 | assert.False(t, ok) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/net/ip/ipv4_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ip 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestExternalIPv4(t *testing.T) { 26 | ip, err := externalIPv4() 27 | assert.Nil(t, err) 28 | assert.NotEmpty(t, ip) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/net/ip/ipv6.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ip 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | ) 23 | 24 | var ( 25 | // IPv6 is external address. 26 | IPv6 net.IP 27 | 28 | // IPv6lookback is lookback address. 29 | IPv6lookback = net.IPv6loopback 30 | ) 31 | 32 | func init() { 33 | ip, err := externalIPv6() 34 | if err != nil { 35 | IPv6 = IPv6lookback 36 | } else { 37 | IPv6 = ip 38 | } 39 | } 40 | 41 | // externalIPv6 returns the available IPv6. 42 | func externalIPv6() (net.IP, error) { 43 | ips, err := ipAddrs() 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | var externalIPs []net.IP 49 | for _, ip := range ips { 50 | ipv4 := ip.To4() 51 | if ipv4 != nil { 52 | continue // skip all ipv4 address 53 | } 54 | 55 | ipv6 := ip.To16() 56 | externalIPs = append(externalIPs, ipv6) 57 | } 58 | 59 | if len(externalIPs) == 0 { 60 | return nil, fmt.Errorf("can not found external ipv6") 61 | } 62 | 63 | return externalIPs[0], nil 64 | } 65 | -------------------------------------------------------------------------------- /pkg/net/ip/ipv6_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ip 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestExternalIPv6(t *testing.T) { 26 | ip, err := externalIPv6() 27 | assert.Nil(t, err) 28 | assert.NotEmpty(t, ip) 29 | } 30 | -------------------------------------------------------------------------------- /pkg/net/ping/ping_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ping 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestPing(t *testing.T) { 26 | ipv4Stat, err := Ping("127.0.0.1") 27 | assert.Nil(t, err) 28 | assert.Equal(t, ipv4Stat.PacketLoss, float64(0)) 29 | assert.Equal(t, len(ipv4Stat.Rtts), 1) 30 | 31 | ipv6Stat, err := Ping("::1") 32 | assert.Nil(t, err) 33 | assert.Equal(t, ipv6Stat.PacketLoss, float64(0)) 34 | assert.Equal(t, len(ipv6Stat.Rtts), 1) 35 | 36 | _, err = Ping("foo") 37 | assert.Error(t, err) 38 | } 39 | -------------------------------------------------------------------------------- /pkg/net/url/url.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package url 18 | 19 | import ( 20 | "net/url" 21 | ) 22 | 23 | // FilterQueryParams filters the query params in the url. 24 | func FilterQueryParams(rawURL string, filteredQueryParams []string) (string, error) { 25 | if len(filteredQueryParams) == 0 { 26 | return rawURL, nil 27 | } 28 | 29 | u, err := url.Parse(rawURL) 30 | if err != nil { 31 | return "", err 32 | } 33 | 34 | hidden := make(map[string]struct{}) 35 | for _, filter := range filteredQueryParams { 36 | hidden[filter] = struct{}{} 37 | } 38 | 39 | var values = make(url.Values) 40 | for k, v := range u.Query() { 41 | if _, ok := hidden[k]; !ok { 42 | values[k] = v 43 | } 44 | } 45 | 46 | u.RawQuery = values.Encode() 47 | return u.String(), nil 48 | } 49 | 50 | // IsValid returns whether the string url is a valid URL. 51 | func IsValid(str string) bool { 52 | u, err := url.Parse(str) 53 | return err == nil && u.Scheme != "" && u.Host != "" 54 | } 55 | -------------------------------------------------------------------------------- /pkg/net/url/url_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package url 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestFilterQuery(t *testing.T) { 26 | url, err := FilterQueryParams("http://www.xx.yy/path?u=f&x=y&m=z&x=s#size", []string{"x", "m"}) 27 | assert.Nil(t, err) 28 | assert.Equal(t, "http://www.xx.yy/path?u=f#size", url) 29 | 30 | url, err = FilterQueryParams("http://www.xx.yy/path?u=f&x=y&m=z&x=s#size", []string{}) 31 | assert.Nil(t, err) 32 | assert.Equal(t, "http://www.xx.yy/path?u=f&x=y&m=z&x=s#size", url) 33 | 34 | url, err = FilterQueryParams(":error_url", []string{"x", "m"}) 35 | assert.NotNil(t, err) 36 | assert.Equal(t, "", url) 37 | } 38 | 39 | func TestIsValid(t *testing.T) { 40 | assert.True(t, IsValid("http://www.x.yy")) 41 | assert.True(t, IsValid("http://www.x.yy/path")) 42 | assert.False(t, IsValid("http:///path")) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/os/user/user.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package user 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | "os/user" 23 | 24 | logger "d7y.io/dragonfly/v2/internal/dflog" 25 | ) 26 | 27 | // HomeDir is the path to the user's home directory. 28 | func HomeDir() string { 29 | u, err := user.Current() 30 | if err != nil { 31 | logger.Warnf("Failed to get current user: %s. Use / as HomeDir", err.Error()) 32 | return "/" 33 | } 34 | 35 | return u.HomeDir 36 | } 37 | 38 | // Username is the username. 39 | func Username() string { 40 | u, err := user.Current() 41 | if err != nil { 42 | logger.Warnf("Failed to get current user: %s. Use os.Getuid() as username", err.Error()) 43 | return fmt.Sprint(os.Getuid()) 44 | } 45 | 46 | return u.Username 47 | } 48 | -------------------------------------------------------------------------------- /pkg/redis/redis_logger.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package redis 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | 23 | logger "d7y.io/dragonfly/v2/internal/dflog" 24 | ) 25 | 26 | type redisLogger struct{} 27 | 28 | func (rl *redisLogger) Printf(ctx context.Context, format string, v ...any) { 29 | logger.CoreLogger.Desugar().Info(fmt.Sprintf(format, v...)) 30 | } 31 | -------------------------------------------------------------------------------- /pkg/retry/retry.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package retry 18 | 19 | import ( 20 | "context" 21 | "time" 22 | 23 | "d7y.io/dragonfly/v2/pkg/math" 24 | ) 25 | 26 | func Run(ctx context.Context, 27 | initBackoff float64, 28 | maxBackoff float64, 29 | maxAttempts int, 30 | f func() (data any, cancel bool, err error)) (any, bool, error) { 31 | var ( 32 | res any 33 | cancel bool 34 | cause error 35 | ) 36 | for i := range maxAttempts { 37 | if i > 0 { 38 | time.Sleep(math.RandBackoffSeconds(initBackoff, maxBackoff, 2.0, i)) 39 | } 40 | 41 | res, cancel, cause = f() 42 | if cause == nil || cancel { 43 | break 44 | } 45 | select { 46 | case <-ctx.Done(): 47 | return nil, cancel, ctx.Err() 48 | default: 49 | } 50 | } 51 | 52 | return res, cancel, cause 53 | } 54 | -------------------------------------------------------------------------------- /pkg/rpc/common/common.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package common 18 | 19 | var ( 20 | // EndOfPiece is the number of end piece. 21 | EndOfPiece = int32(1) << 30 22 | 23 | // BeginOfPiece is the number of begin piece. 24 | BeginOfPiece = int32(-1) 25 | ) 26 | -------------------------------------------------------------------------------- /pkg/rpc/dfdaemon/client/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "time" 21 | ) 22 | 23 | const ( 24 | // contextTimeout is timeout of grpc invoke. 25 | contextTimeout = 2 * time.Minute 26 | 27 | // maxRetries is maximum number of retries. 28 | maxRetries = 3 29 | 30 | // backoffWaitBetween is waiting for a fixed period of 31 | // time between calls in backoff linear. 32 | backoffWaitBetween = 500 * time.Millisecond 33 | ) 34 | -------------------------------------------------------------------------------- /pkg/rpc/manager/client/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "time" 21 | ) 22 | 23 | const ( 24 | // contextTimeout is timeout of grpc invoke. 25 | contextTimeout = 2 * time.Minute 26 | 27 | // maxRetries is maximum number of retries. 28 | maxRetries = 3 29 | 30 | // backoffWaitBetween is waiting for a fixed period of 31 | // time between calls in backoff linear. 32 | backoffWaitBetween = 500 * time.Millisecond 33 | ) 34 | -------------------------------------------------------------------------------- /pkg/rpc/scheduler/client/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "time" 21 | ) 22 | 23 | const ( 24 | // contextTimeout is timeout of grpc invoke. 25 | contextTimeout = 2 * time.Minute 26 | 27 | // maxRetries is maximum number of retries. 28 | maxRetries = 3 29 | 30 | // backoffWaitBetween is waiting for a fixed period of 31 | // time between calls in backoff linear. 32 | backoffWaitBetween = 500 * time.Millisecond 33 | ) 34 | -------------------------------------------------------------------------------- /pkg/rpc/vsock.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package rpc 18 | 19 | import ( 20 | "context" 21 | "net" 22 | "net/url" 23 | "strconv" 24 | "strings" 25 | 26 | "github.com/mdlayher/vsock" 27 | 28 | "d7y.io/dragonfly/v2/pkg/dfnet" 29 | ) 30 | 31 | // VsockDialer is the dialer for vsock. 32 | func VsockDialer(ctx context.Context, address string) (net.Conn, error) { 33 | u, err := url.Parse(address) 34 | if err != nil { 35 | return nil, err 36 | } 37 | 38 | cid, err := strconv.ParseUint(u.Hostname(), 10, 32) 39 | if err != nil { 40 | return nil, err 41 | } 42 | 43 | port, err := strconv.ParseUint(u.Port(), 10, 32) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | conn, err := vsock.Dial(uint32(cid), uint32(port), nil) 49 | if err != nil { 50 | return nil, err 51 | } 52 | 53 | return conn, nil 54 | } 55 | 56 | // IsVsock returns whether the address is vsock. 57 | func IsVsock(target string) bool { 58 | return strings.HasPrefix(target, string(dfnet.VSOCK)) 59 | } 60 | -------------------------------------------------------------------------------- /pkg/safe/safe.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package safe 18 | 19 | import ( 20 | "fmt" 21 | "runtime/debug" 22 | 23 | logger "d7y.io/dragonfly/v2/internal/dflog" 24 | ) 25 | 26 | // Safe call function. 27 | func Call(f func()) (err error) { 28 | defer func() { 29 | if r := recover(); r != nil { 30 | err = fmt.Errorf("%v", r) 31 | logger.Errorf("panic: %s", string(debug.Stack())) 32 | debug.PrintStack() 33 | } 34 | }() 35 | 36 | f() 37 | 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /pkg/source/clients/httpprotocol/header.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package httpprotocol 18 | 19 | import "github.com/go-http-utils/headers" 20 | 21 | var PassThroughHeaders = map[string]struct{}{ 22 | // TODO implement cache control in dragonfly, then enable the following header pass through 23 | // headers.CacheControl: {}, 24 | // headers.ETag: {}, 25 | // headers.Expires: {}, 26 | // headers.LastModified: {}, 27 | 28 | headers.Authorization: {}, 29 | headers.ContentType: {}, 30 | headers.ContentRange: {}, 31 | headers.ContentEncoding: {}, 32 | headers.WWWAuthenticate: {}, 33 | } 34 | 35 | func AddPassThroughHeader(header string) { 36 | PassThroughHeaders[header] = struct{}{} 37 | } 38 | -------------------------------------------------------------------------------- /pkg/source/loader/dfs.go.example: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/example" // Register dfs client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/gs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2025 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/gsprotocol" // Register gcs client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/hdfs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/hdfsprotocol" // Register hdfs client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/http.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/httpprotocol" // Register http client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/oras.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/orasprotocol" // Register oras client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/oss.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/ossprotocol" // Register oss client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/loader/s3.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package loader 18 | 19 | import ( 20 | _ "d7y.io/dragonfly/v2/pkg/source/clients/s3protocol" // Register s3 client 21 | ) 22 | -------------------------------------------------------------------------------- /pkg/source/metadata.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package source 18 | 19 | type Metadata struct { 20 | Status string 21 | StatusCode int 22 | Header Header 23 | // SupportRange indicates source supports partial download, like Range in http request 24 | SupportRange bool 25 | // ContentLength indicates the current content length for the target request 26 | // ContentLength int64 27 | // TotalContentLength indicates the total content length for the target request 28 | // eg, for http response header: 29 | // Content-Range: bytes 0-9/2443 30 | // 2443 is the TotalContentLength, 10 is the ContentLength 31 | TotalContentLength int64 32 | 33 | Validate func() error 34 | Temporary bool 35 | } 36 | -------------------------------------------------------------------------------- /pkg/source/plugin.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package source 18 | 19 | import ( 20 | "errors" 21 | 22 | logger "d7y.io/dragonfly/v2/internal/dflog" 23 | "d7y.io/dragonfly/v2/internal/dfplugin" 24 | ) 25 | 26 | const ( 27 | pluginMetadataScheme = "scheme" 28 | ) 29 | 30 | func LoadPlugin(dir, scheme string) (ResourceClient, error) { 31 | // TODO init option 32 | logger.Debugf("try to load source plugin: %s", scheme) 33 | client, meta, err := dfplugin.Load(dir, dfplugin.PluginTypeResource, scheme, map[string]string{}) 34 | if err != nil { 35 | logger.Errorf("load source plugin error: %s", err) 36 | return nil, err 37 | } 38 | 39 | if meta[pluginMetadataScheme] != scheme { 40 | logger.Errorf("load source plugin error: support scheme not match") 41 | return nil, errors.New("support schema not match") 42 | } 43 | 44 | rc, ok := client.(ResourceClient) 45 | if !ok { 46 | logger.Errorf("invalid client, not a ResourceClient") 47 | return nil, errors.New("invalid client, not a ResourceClient") 48 | } 49 | 50 | logger.Debugf("loaded source plugin %s", scheme) 51 | return rc, nil 52 | } 53 | -------------------------------------------------------------------------------- /pkg/source/request_fixture.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package source 18 | 19 | import ( 20 | "fmt" 21 | 22 | "go.uber.org/mock/gomock" 23 | ) 24 | 25 | // RequestEq for gomock 26 | func RequestEq(url string) gomock.Matcher { 27 | return requestMatcher{url} 28 | } 29 | 30 | type requestMatcher struct { 31 | url string 32 | } 33 | 34 | // Matches returns whether x is a match. 35 | func (req requestMatcher) Matches(x any) bool { 36 | return x.(*Request).URL.String() == req.url 37 | } 38 | 39 | // String describes what the matcher matches. 40 | func (req requestMatcher) String() string { 41 | return fmt.Sprintf("is equal to %v (%T)", req.url, req.url) 42 | } 43 | -------------------------------------------------------------------------------- /pkg/strings/strings.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package strings 18 | 19 | import ( 20 | "slices" 21 | "strings" 22 | ) 23 | 24 | // IsBlank determines whether the string is empty. 25 | func IsBlank(s string) bool { 26 | return strings.TrimSpace(s) == "" 27 | } 28 | 29 | // Contains reports whether the string contains the element. 30 | func Contains(slice []string, ele string) bool { 31 | return slices.Contains(slice, ele) 32 | } 33 | 34 | // Remove the duplicate elements in the string slice. 35 | func Unique(slice []string) []string { 36 | keys := make(map[string]bool) 37 | result := []string{} 38 | for _, entry := range slice { 39 | if _, ok := keys[entry]; !ok { 40 | keys[entry] = true 41 | result = append(result, entry) 42 | } 43 | } 44 | 45 | return result 46 | } 47 | 48 | // Concat concatenates multiple string slices. 49 | func Concat(slices ...[]string) []string { 50 | var result []string 51 | for _, slice := range slices { 52 | result = append(result, slice...) 53 | } 54 | return result 55 | } 56 | -------------------------------------------------------------------------------- /pkg/structure/structure.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package structure 18 | 19 | import ( 20 | "encoding/json" 21 | ) 22 | 23 | // StructToMap coverts struct to map. 24 | func StructToMap(t any) (map[string]any, error) { 25 | var m map[string]any 26 | b, err := json.Marshal(t) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | if err := json.Unmarshal(b, &m); err != nil { 32 | return nil, err 33 | } 34 | 35 | return m, nil 36 | } 37 | 38 | // MapToStruct converts map to struct. 39 | func MapToStruct(m map[string]any, t any) error { 40 | if m == nil { 41 | return nil 42 | } 43 | 44 | b, err := json.Marshal(m) 45 | if err != nil { 46 | return err 47 | } 48 | 49 | if err := json.Unmarshal(b, t); err != nil { 50 | return err 51 | } 52 | 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /pkg/time/time.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package time 18 | 19 | import ( 20 | "time" 21 | ) 22 | 23 | // NanoToTime converts an int64 nanoseconds to a time 24 | func NanoToTime(nsec int64) time.Time { 25 | return time.Unix(0, nsec) 26 | } 27 | 28 | // SubNano returns the difference between two nanoseconds 29 | func SubNano(x int64, y int64) time.Duration { 30 | return NanoToTime(x).Sub(NanoToTime(y)) 31 | } 32 | -------------------------------------------------------------------------------- /scheduler/config/testdata/ca.crt: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /scheduler/config/testdata/scheduler.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | advertiseIP: 127.0.0.1 3 | advertisePort: 8004 4 | listenIP: 0.0.0.0 5 | port: 8002 6 | host: foo 7 | tls: 8 | caCert: foo 9 | cert: foo 10 | key: foo 11 | cacheDir: foo 12 | logDir: foo 13 | pluginDir: foo 14 | dataDir: foo 15 | logMaxSize: 512 16 | logMaxAge: 5 17 | logMaxBackups: 3 18 | 19 | scheduler: 20 | algorithm: default 21 | backToSourceCount: 3 22 | retryBackToSourceLimit: 2 23 | retryLimit: 10 24 | retryInterval: 10s 25 | gc: 26 | pieceDownloadTimeout: 5s 27 | peerGCInterval: 10s 28 | peerTTL: 60s 29 | taskGCInterval: 30s 30 | hostGCInterval: 1m 31 | hostTTL: 1m 32 | 33 | database: 34 | redis: 35 | addrs: [ "foo", "bar" ] 36 | masterName: "baz" 37 | host: 127.0.0.1 38 | port: 6379 39 | password: foo 40 | brokerDB: 1 41 | backendDB: 2 42 | poolSize: 10 43 | poolTimeout: 1s 44 | 45 | dynConfig: 46 | refreshInterval: 10s 47 | 48 | host: 49 | idc: foo 50 | location: baz 51 | 52 | manager: 53 | addr: 127.0.0.1:65003 54 | tls: 55 | caCert: foo 56 | cert: foo 57 | key: foo 58 | schedulerClusterID: 1 59 | keepAlive: 60 | interval: 5s 61 | 62 | seedPeer: 63 | enable: true 64 | tls: 65 | caCert: foo 66 | cert: foo 67 | key: foo 68 | taskDownloadTimeout: 12h 69 | 70 | job: 71 | enable: true 72 | globalWorkerNum: 1 73 | schedulerWorkerNum: 1 74 | localWorkerNum: 5 75 | 76 | metrics: 77 | enable: false 78 | addr: ":8000" 79 | enableHost: true 80 | 81 | network: 82 | enableIPv6: true 83 | -------------------------------------------------------------------------------- /scheduler/job/mocks/job_mock.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: job.go 3 | // 4 | // Generated by this command: 5 | // 6 | // mockgen -destination mocks/job_mock.go -source job.go -package mocks 7 | // 8 | 9 | // Package mocks is a generated GoMock package. 10 | package mocks 11 | 12 | import ( 13 | reflect "reflect" 14 | 15 | gomock "go.uber.org/mock/gomock" 16 | ) 17 | 18 | // MockJob is a mock of Job interface. 19 | type MockJob struct { 20 | ctrl *gomock.Controller 21 | recorder *MockJobMockRecorder 22 | isgomock struct{} 23 | } 24 | 25 | // MockJobMockRecorder is the mock recorder for MockJob. 26 | type MockJobMockRecorder struct { 27 | mock *MockJob 28 | } 29 | 30 | // NewMockJob creates a new mock instance. 31 | func NewMockJob(ctrl *gomock.Controller) *MockJob { 32 | mock := &MockJob{ctrl: ctrl} 33 | mock.recorder = &MockJobMockRecorder{mock} 34 | return mock 35 | } 36 | 37 | // EXPECT returns an object that allows the caller to indicate expected use. 38 | func (m *MockJob) EXPECT() *MockJobMockRecorder { 39 | return m.recorder 40 | } 41 | 42 | // Serve mocks base method. 43 | func (m *MockJob) Serve() { 44 | m.ctrl.T.Helper() 45 | m.ctrl.Call(m, "Serve") 46 | } 47 | 48 | // Serve indicates an expected call of Serve. 49 | func (mr *MockJobMockRecorder) Serve() *gomock.Call { 50 | mr.mock.ctrl.T.Helper() 51 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Serve", reflect.TypeOf((*MockJob)(nil).Serve)) 52 | } 53 | -------------------------------------------------------------------------------- /scheduler/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2023 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package metrics 18 | 19 | import ( 20 | "net/http" 21 | "testing" 22 | 23 | "google.golang.org/grpc" 24 | 25 | "d7y.io/dragonfly/v2/scheduler/config" 26 | ) 27 | 28 | func TestNew(t *testing.T) { 29 | cfg := &config.MetricsConfig{ 30 | Addr: "localhost:8080", 31 | } 32 | svr := grpc.NewServer() 33 | server := New(cfg, svr) 34 | 35 | if server.Addr != cfg.Addr { 36 | t.Errorf("expected server.Addr to be %s, but got %s", cfg.Addr, server.Addr) 37 | } 38 | 39 | if _, ok := server.Handler.(*http.ServeMux); !ok { 40 | t.Errorf("expected server.Handler to be a *http.ServeMux, but got %T", server.Handler) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /scheduler/resource/standard/piece.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package standard 18 | 19 | import ( 20 | "time" 21 | 22 | commonv2 "d7y.io/api/v2/pkg/apis/common/v2" 23 | 24 | "d7y.io/dragonfly/v2/pkg/digest" 25 | ) 26 | 27 | // IsPieceBackToSource returns whether the piece is downloaded back-to-source. 28 | func IsPieceBackToSource(parentID string) bool { 29 | return parentID == "" 30 | } 31 | 32 | // Piece represents information of piece. 33 | type Piece struct { 34 | // Piece number. 35 | Number int32 36 | // Parent peer id. 37 | ParentID string 38 | // Piece offset. 39 | Offset uint64 40 | // Piece length. 41 | Length uint64 42 | // Digest of the piece data. 43 | Digest *digest.Digest 44 | // Traffic type. 45 | TrafficType commonv2.TrafficType 46 | // Downloading piece costs time. 47 | Cost time.Duration 48 | // Piece create time. 49 | CreatedAt time.Time 50 | } 51 | -------------------------------------------------------------------------------- /scheduler/resource/standard/piece_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package standard 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestResource_IsPieceBackToSource(t *testing.T) { 26 | tests := []struct { 27 | name string 28 | parentID string 29 | expect func(t *testing.T, ok bool) 30 | }{ 31 | { 32 | name: "piece is back-to-source", 33 | parentID: "", 34 | expect: func(t *testing.T, ok bool) { 35 | assert := assert.New(t) 36 | assert.True(ok) 37 | }, 38 | }, 39 | { 40 | name: "piece is not back-to-source", 41 | parentID: "foo", 42 | expect: func(t *testing.T, ok bool) { 43 | assert := assert.New(t) 44 | assert.False(ok) 45 | }, 46 | }, 47 | } 48 | 49 | for _, tc := range tests { 50 | t.Run(tc.name, func(t *testing.T) { 51 | tc.expect(t, IsPieceBackToSource(tc.parentID)) 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scheduler/rpcserver/rpcserver.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package rpcserver 18 | 19 | import ( 20 | "google.golang.org/grpc" 21 | 22 | "d7y.io/dragonfly/v2/pkg/rpc/scheduler/server" 23 | "d7y.io/dragonfly/v2/scheduler/config" 24 | "d7y.io/dragonfly/v2/scheduler/resource/persistentcache" 25 | "d7y.io/dragonfly/v2/scheduler/resource/standard" 26 | "d7y.io/dragonfly/v2/scheduler/scheduling" 27 | ) 28 | 29 | // New returns a new scheduler server from the given options. 30 | func New( 31 | cfg *config.Config, 32 | resource standard.Resource, 33 | persistentCacheResource persistentcache.Resource, 34 | scheduling scheduling.Scheduling, 35 | dynconfig config.DynconfigInterface, 36 | opts ...grpc.ServerOption, 37 | ) *grpc.Server { 38 | return server.New( 39 | newSchedulerServerV1(cfg, resource, scheduling, dynconfig), 40 | newSchedulerServerV2(cfg, resource, persistentCacheResource, scheduling, dynconfig), 41 | opts...) 42 | } 43 | -------------------------------------------------------------------------------- /scheduler/scheduling/evaluator/plugin.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package evaluator 18 | 19 | import ( 20 | "errors" 21 | 22 | "d7y.io/dragonfly/v2/internal/dfplugin" 23 | ) 24 | 25 | const ( 26 | pluginName = "evaluator" 27 | ) 28 | 29 | func LoadPlugin(dir string) (Evaluator, error) { 30 | client, _, err := dfplugin.Load(dir, dfplugin.PluginTypeScheduler, pluginName, map[string]string{}) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | if rc, ok := client.(Evaluator); ok { 36 | return rc, err 37 | } 38 | return nil, errors.New("invalid evaluator plugin") 39 | } 40 | -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # Test 2 | 3 | Dragonfly includes unit tests and E2E tests. 4 | 5 | ## Unit tests 6 | 7 | Unit tests is in the project directory. 8 | 9 | ### Running unit tests 10 | 11 | ```bash 12 | make test 13 | ``` 14 | 15 | ### Running unit tests with coverage reports 16 | 17 | ```bash 18 | make test-coverage 19 | ``` 20 | 21 | ## E2E tests 22 | 23 | E2E tests is in `test/e2e` path. 24 | 25 | ### Running E2E tests 26 | 27 | ```bash 28 | make e2e-test 29 | ``` 30 | 31 | ### Running E2E tests with coverage reports 32 | 33 | ```bash 34 | make e2e-test-coverage 35 | ``` 36 | 37 | ### Clean E2E tests environment 38 | 39 | ```bash 40 | make clean-e2e-test 41 | ``` 42 | -------------------------------------------------------------------------------- /test/testdata/charts/config-nydus.yaml: -------------------------------------------------------------------------------- 1 | name: nydus-snapshotter 2 | pullPolicy: Always 3 | hostNetwork: true 4 | resources: 5 | requests: 6 | cpu: "0" 7 | memory: "0" 8 | limits: 9 | cpu: "1" 10 | memory: "1Gi" 11 | 12 | dragonfly: 13 | enable: true 14 | mirrorConfig: 15 | - host: "http://127.0.0.1:4001" 16 | auth_through: false 17 | headers: 18 | "X-Dragonfly-Registry": "https://ghcr.io" 19 | ping_url: "http://127.0.0.1:4003/healthy" 20 | 21 | containerRuntime: 22 | initContainerImage: ghcr.io/liubin/toml-cli:v0.0.7 23 | containerd: 24 | enable: true 25 | configFile: "/etc/containerd/config.toml" 26 | -------------------------------------------------------------------------------- /test/testdata/containerd/config.toml: -------------------------------------------------------------------------------- 1 | # explicitly use v2 config format 2 | version = 2 3 | 4 | [debug] 5 | level = "debug" 6 | 7 | [plugins."io.containerd.grpc.v1.cri".containerd] 8 | # save disk space when using a single snapshotter 9 | discard_unpacked_layers = false 10 | # explicitly use default snapshotter so we can sed it in entrypoint 11 | snapshotter = "overlayfs" 12 | # explicit default here, as we're configuring it below 13 | default_runtime_name = "runc" 14 | [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] 15 | # set default runtime handler to v2, which has a per-pod shim 16 | runtime_type = "io.containerd.runc.v2" 17 | 18 | # Setup a runtime with the magic name ("test-handler") used for Kubernetes 19 | # runtime class tests ... 20 | [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler] 21 | runtime_type = "io.containerd.runc.v2" 22 | 23 | [plugins."io.containerd.grpc.v1.cri"] 24 | # use fixed sandbox image 25 | sandbox_image = "registry.k8s.io/pause:3.5" 26 | # allow hugepages controller to be missing 27 | # see https://github.com/containerd/cri/pull/1501 28 | tolerate_missing_hugepages_controller = true 29 | # restrict_oom_score_adj needs to be true when running inside UserNS (rootless) 30 | restrict_oom_score_adj = false 31 | -------------------------------------------------------------------------------- /test/testdata/k8s/dufs.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: dragonfly-e2e 6 | 7 | --- 8 | apiVersion: v1 9 | kind: Service 10 | metadata: 11 | name: dufs 12 | namespace: dragonfly-e2e 13 | spec: 14 | selector: 15 | app: dragonfly 16 | component: dufs 17 | type: ClusterIP 18 | ports: 19 | - name: server 20 | port: 80 21 | protocol: TCP 22 | targetPort: 5000 23 | 24 | --- 25 | apiVersion: apps/v1 26 | kind: StatefulSet 27 | metadata: 28 | name: dufs 29 | namespace: dragonfly-e2e 30 | spec: 31 | serviceName: dufs 32 | selector: 33 | matchLabels: 34 | app: dragonfly 35 | component: dufs 36 | replicas: 1 37 | template: 38 | metadata: 39 | labels: 40 | app: dragonfly 41 | component: dufs 42 | spec: 43 | containers: 44 | - name: dufs 45 | image: sigoden/dufs:v0.43.0 46 | command: ["dufs"] 47 | args: 48 | - "/data" 49 | - "-A" 50 | - "-b" 51 | - "0.0.0.0" 52 | - "-p" 53 | - "5000" 54 | imagePullPolicy: "IfNotPresent" 55 | ports: 56 | - containerPort: 5000 57 | volumeMounts: 58 | - name: data 59 | mountPath: /data 60 | volumes: 61 | - name: data 62 | hostPath: 63 | path: /tmp/artifact/dufs 64 | -------------------------------------------------------------------------------- /test/testdata/k8s/nydus.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: nydus-pod 5 | spec: 6 | containers: 7 | - name: nginx 8 | image: ghcr.io/dragonflyoss/image-service/nginx:nydus-latest 9 | imagePullPolicy: Always 10 | command: ["sh", "-c"] 11 | args: 12 | - tail -f /dev/null 13 | -------------------------------------------------------------------------------- /test/testdata/kind/config.yaml: -------------------------------------------------------------------------------- 1 | kind: Cluster 2 | apiVersion: kind.x-k8s.io/v1alpha4 3 | networking: 4 | ipFamily: dual 5 | nodes: 6 | - role: control-plane 7 | image: kindest/node:v1.23.4 8 | extraMounts: 9 | - hostPath: ./test/testdata/containerd/config.toml 10 | containerPath: /etc/containerd/config.toml 11 | - hostPath: /tmp/artifact 12 | containerPath: /tmp/artifact 13 | - hostPath: /dev/fuse 14 | containerPath: /dev/fuse 15 | - role: worker 16 | image: kindest/node:v1.23.4 17 | extraPortMappings: 18 | - containerPort: 4001 19 | hostPort: 4001 20 | protocol: TCP 21 | - containerPort: 4003 22 | hostPort: 4003 23 | protocol: TCP 24 | - containerPort: 30802 25 | hostPort: 8002 26 | protocol: TCP 27 | extraMounts: 28 | - hostPath: ./test/testdata/containerd/config.toml 29 | containerPath: /etc/containerd/config.toml 30 | - hostPath: /tmp/artifact 31 | containerPath: /tmp/artifact 32 | - hostPath: /dev/fuse 33 | containerPath: /dev/fuse 34 | -------------------------------------------------------------------------------- /version/platform_darwin.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package version 18 | 19 | const ( 20 | osArch = "darwin" 21 | ) 22 | -------------------------------------------------------------------------------- /version/platform_linux.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package version 18 | 19 | const ( 20 | osArch = "linux" 21 | ) 22 | -------------------------------------------------------------------------------- /version/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The Dragonfly Authors 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package version 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | var ( 24 | Major = "2" 25 | Minor = "0" 26 | GitVersion = "v2.2.0" 27 | GitCommit = "unknown" 28 | Platform = osArch 29 | BuildTime = "unknown" 30 | GoVersion = "unknown" 31 | Gotags = "unknown" 32 | Gogcflags = "unknown" 33 | ) 34 | 35 | func Version() string { 36 | return fmt.Sprintf("Major: %s, Minor: %s, GitVersion: %s, GitCommit: %s, Platform: %s, BuildTime: %s, GoVersion: %s, Gotags: %s, Gogcflags: %s", Major, 37 | Minor, GitVersion, GitCommit, Platform, BuildTime, GoVersion, Gotags, Gogcflags) 38 | } 39 | --------------------------------------------------------------------------------